From 6ddb57146b0eff999a490a61a75673033379bf8c Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 1 Jun 2021 19:00:06 -0400 Subject: [PATCH 001/606] CI: still debugging... --- .github/workflows/main.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 692f04f7a..37690b94d 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -25,9 +25,10 @@ jobs: with: repository: libsdl-org/SDL ref: release-2.0.14 - path: sdl12-compat/SDL2 + path: SDL2 - name: Configure CMake run: cmake -DSDL2_INCLUDE_DIR="${{ github.workspace }}/SDL2/include" -B build ${{ matrix.platform.flags }} - name: Build run: cmake --build build/ - + - name: debugging + run: find "${{ github.workspace }}" From eb86fe022a53dcde54d2a6d41089a74a8c11ab5e Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 1 Jun 2021 19:03:47 -0400 Subject: [PATCH 002/606] CI: STILL debugging --- .github/workflows/main.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 37690b94d..684f80cc0 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -28,7 +28,7 @@ jobs: path: SDL2 - name: Configure CMake run: cmake -DSDL2_INCLUDE_DIR="${{ github.workspace }}/SDL2/include" -B build ${{ matrix.platform.flags }} - - name: Build - run: cmake --build build/ - name: debugging run: find "${{ github.workspace }}" + - name: Build + run: cmake --build build/ From 229f0ec891885ce2a96f6ccc391ee12e30fe455c Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 1 Jun 2021 20:42:49 -0400 Subject: [PATCH 003/606] CI: Need the Mesa headers for testgl.c --- .github/workflows/main.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 684f80cc0..24c63bf9f 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -17,7 +17,7 @@ jobs: if: runner.os == 'Linux' run: | sudo apt-get update - sudo apt-get install cmake ninja-build + sudo apt-get install cmake ninja-build libgl1-mesa-dev - name: Get sdl12-compat sources uses: actions/checkout@v2 - name: Get SDL2 headers @@ -28,7 +28,5 @@ jobs: path: SDL2 - name: Configure CMake run: cmake -DSDL2_INCLUDE_DIR="${{ github.workspace }}/SDL2/include" -B build ${{ matrix.platform.flags }} - - name: debugging - run: find "${{ github.workspace }}" - name: Build run: cmake --build build/ From dae50d7df330725a34f4cbd5da58e6537f0d5425 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 1 Jun 2021 20:44:07 -0400 Subject: [PATCH 004/606] CI: Need GLU headers for testgl.c, too. --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 24c63bf9f..f46387b9e 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -17,7 +17,7 @@ jobs: if: runner.os == 'Linux' run: | sudo apt-get update - sudo apt-get install cmake ninja-build libgl1-mesa-dev + sudo apt-get install cmake ninja-build libgl1-mesa-dev libglu1-mesa-dev - name: Get sdl12-compat sources uses: actions/checkout@v2 - name: Get SDL2 headers From 53062d97bf108e229ec771baddd01d57315abbfd Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 1 Jun 2021 21:09:11 -0400 Subject: [PATCH 005/606] Make GCC and Clang fail if there's a declaration after a statement. (that is, make it automatically catch C89 incompatibilities before Ozkan has to clean up my messes for me later.) --- CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index fe9e8ecd6..f73ac90ea 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,6 +37,10 @@ include(GNUInstallDirs) include("cmake/modules/FindSDL2.cmake") target_include_directories(SDL PRIVATE ${SDL2_INCLUDE_DIRS}) +if (CMAKE_C_COMPILER_ID MATCHES "Clang|GNU") + add_definitions("-Werror=declaration-after-statement") # force this universally. +endif() + # avoid DLL having 'lib' prefix with Windows MinGW builds if(WIN32) set(CMAKE_SHARED_LIBRARY_PREFIX "") From 011856cc2d7124028e993687c3e8bff274a9ca10 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Wed, 2 Jun 2021 05:09:06 +0300 Subject: [PATCH 006/606] remove the dummy configure script. --- configure | 4 ---- 1 file changed, 4 deletions(-) delete mode 100755 configure diff --git a/configure b/configure deleted file mode 100755 index 7639dd876..000000000 --- a/configure +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh - -echo 'Please use CMake ( http://www.cmake.org/ ) to generate project files.' -exit 1 From 4a04f9230781fe871790392e6d34fe7498be4878 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Wed, 2 Jun 2021 05:10:02 +0300 Subject: [PATCH 007/606] add -Wall to CFLAGS, too, for gcc/clang. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f73ac90ea..f5ef689c4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -38,7 +38,7 @@ include("cmake/modules/FindSDL2.cmake") target_include_directories(SDL PRIVATE ${SDL2_INCLUDE_DIRS}) if (CMAKE_C_COMPILER_ID MATCHES "Clang|GNU") - add_definitions("-Werror=declaration-after-statement") # force this universally. + add_definitions("-Wall -Werror=declaration-after-statement") # force these universally. endif() # avoid DLL having 'lib' prefix with Windows MinGW builds From 3ad12eed638f4e2d3dc0de88f4f39c44ada347b7 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 1 Jun 2021 21:53:16 -0400 Subject: [PATCH 008/606] testgl.c has to link against OpenGL32.lib on Windows. --- CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index f5ef689c4..515c0cd45 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -139,6 +139,8 @@ if(SDL12TESTS) if(APPLE) target_link_libraries(testgl "-framework OpenGL") set_target_properties(testgl PROPERTIES COMPILE_DEFINITIONS "GL_SILENCE_DEPRECATION=1") + elseif(WIN32) + target_link_libraries(testgl "OpenGL32") else() target_link_libraries(testgl "GL") endif() From d85e000ab814a6e40a276170e8b17dd022cbcbd2 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 1 Jun 2021 22:03:17 -0400 Subject: [PATCH 009/606] Turn off MSVC's aggressive C runtime warnings for the old test programs. --- CMakeLists.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 515c0cd45..59e7762eb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -98,6 +98,12 @@ if(SDL12TESTS) target_include_directories(${_NAME} PRIVATE "include/SDL") target_link_libraries(${_NAME} SDL) set_target_properties(${_NAME} PROPERTIES COMPILE_DEFINITIONS "HAVE_OPENGL") + # Turn off MSVC's aggressive C runtime warnings for the old test programs. + if(MSVC) + set_target_properties(${_NAME} PROPERTIES COMPILE_DEFINITIONS "HAVE_OPENGL;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE") + else() + set_target_properties(${_NAME} PROPERTIES COMPILE_DEFINITIONS "HAVE_OPENGL") + endif() if(MATH_LIBRARY) target_link_libraries(${_NAME} ${MATH_LIBRARY}) endif() From 259f22f80be8b9c4ce35805785c23b5d69c01e07 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 1 Jun 2021 22:20:42 -0400 Subject: [PATCH 010/606] Fixed a few test app type conversions that Visual Studio complains about. --- test/graywin.c | 2 +- test/testdyngl.c | 8 ++++---- test/testoverlay.c | 16 ++++++++-------- test/testoverlay2.c | 20 ++++++++++---------- test/testsprite.c | 6 +++--- 5 files changed, 26 insertions(+), 26 deletions(-) diff --git a/test/graywin.c b/test/graywin.c index 456311496..c1f8a5dd3 100644 --- a/test/graywin.c +++ b/test/graywin.c @@ -24,7 +24,7 @@ void DrawBox(SDL_Surface *screen, int X, int Y, int width, int height) /* Seed the random number generator */ if ( seeded == 0 ) { - srand(time(NULL)); + srand((unsigned int) time(NULL)); seeded = 1; } diff --git a/test/testdyngl.c b/test/testdyngl.c index a20bd1a48..538b47fcb 100644 --- a/test/testdyngl.c +++ b/test/testdyngl.c @@ -138,9 +138,9 @@ int main(int argc,char *argv[]) for(i=0;iformat, 255, 0, 0); SDL_Rect r; - r.x = (sin((float)t * 2 * 3.1459) + 1.0) / 2.0 * (screen->w-20); + r.x = (Sint16) ((sin((float)t * 2 * 3.1459) + 1.0) / 2.0 * (screen->w-20)); r.y = 0; r.w = 20; r.h = screen->h; @@ -137,7 +137,7 @@ Uint32 FastestFlags(Uint32 flags, int width, int height, int bpp) /* Direct hardware blitting without double-buffering causes really bad flickering. */ - if ( info->video_mem*1024 > (height*width*bpp/8) ) { + if ( info->video_mem*1024 > ((Uint32)(height*width*bpp/8)) ) { flags |= SDL_DOUBLEBUF; } else { flags &= ~SDL_HWSURFACE; @@ -239,7 +239,7 @@ int main(int argc, char *argv[]) sprite_rects += numsprites; sprite_w = sprite->w; sprite_h = sprite->h; - srand(time(NULL)); + srand((unsigned int) time(NULL)); for ( i=0; iw - sprite_w); positions[i].y = rand()%(screen->h - sprite_h); From dc76b7c9b70e957b079cd52ef6a74a44c0ec4899 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Wed, 2 Jun 2021 05:55:02 +0300 Subject: [PATCH 011/606] remove duplicated set_target_properties() --- CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 59e7762eb..6256c3a06 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -97,7 +97,6 @@ if(SDL12TESTS) add_executable(${_NAME} ${_SRCS}) target_include_directories(${_NAME} PRIVATE "include/SDL") target_link_libraries(${_NAME} SDL) - set_target_properties(${_NAME} PROPERTIES COMPILE_DEFINITIONS "HAVE_OPENGL") # Turn off MSVC's aggressive C runtime warnings for the old test programs. if(MSVC) set_target_properties(${_NAME} PROPERTIES COMPILE_DEFINITIONS "HAVE_OPENGL;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE") From fd7ed1f169cd1dee0602222a92344ae6d9ae65ca Mon Sep 17 00:00:00 2001 From: David Gow Date: Sun, 30 May 2021 21:57:40 +0800 Subject: [PATCH 012/606] Scale mouse events with OpenGL Logical Scaling For non-OpenGL windows, mouse coordinates are scaled by SDL_RenderSetLogicalSize(), but with OpenGL Logical Scaling, we need to do this ourselves. Extract the viewport calculations for OpenGL Logical Scaling into their own function, which is called on mouse events and used to adjust the mouse coordinates. Because they're adjusted early enough in the event processing loop, they're already scaled by the time MousePosition is set. Note that the scaled events are passed down to any other SDL2 event handlers that might exist, as we modify the SDL2 events in the filter. Since this basically matches what SDL_RenderSetLogicalSize() does, it hopefully won't be a problem. --- src/SDL12_compat.c | 97 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 68 insertions(+), 29 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 6b3782566..d318161ef 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1902,6 +1902,69 @@ SDL_EventState(Uint8 type, int state) return retval; } +static SDL_Rect +GetOpenGLLogicalScalingViewport() +{ + float want_aspect, real_aspect; + int drawablew, drawableh; + SDL_Rect dstrect; + SDL20_GL_GetDrawableSize(VideoWindow20, &drawablew, &drawableh); + + want_aspect = ((float) OpenGLLogicalScalingWidth) / ((float) OpenGLLogicalScalingHeight); + real_aspect = ((float) drawablew) / ((float) drawableh); + + if (SDL20_fabsf(want_aspect-real_aspect) < 0.0001f) { + /* The aspect ratios are the same, just scale appropriately */ + dstrect.x = 0; + dstrect.y = 0; + dstrect.w = drawablew; + dstrect.h = drawableh; + } else if (want_aspect > real_aspect) { + /* We want a wider aspect ratio than is available - letterbox it */ + const float scale = ((float) drawablew) / OpenGLLogicalScalingWidth; + dstrect.x = 0; + dstrect.w = drawablew; + dstrect.h = (int)SDL20_floorf(OpenGLLogicalScalingHeight * scale); + dstrect.y = (drawableh - dstrect.h) / 2; + } else { + /* We want a narrower aspect ratio than is available - use side-bars */ + const float scale = ((float)drawableh) / OpenGLLogicalScalingHeight; + dstrect.y = 0; + dstrect.h = drawableh; + dstrect.w = (int)SDL20_floorf(OpenGLLogicalScalingWidth * scale); + dstrect.x = (drawablew - dstrect.w) / 2; + } + + return dstrect; +} + +static void +AdjustOpenGLLogicalScalingPoint(int *x, int *y) +{ + SDL_Rect viewport; + float scale_x, scale_y; + int adjusted_x, adjusted_y; + + /* Don't adjust anything if we're not using Logical Scaling */ + if (!OpenGLLogicalScalingFBO) { + return; + } + + /* These will need to be scaled further if we want to support High-DPI */ + viewport = GetOpenGLLogicalScalingViewport(); + + scale_x = (float)OpenGLLogicalScalingWidth / viewport.w; + scale_y = (float)OpenGLLogicalScalingHeight / viewport.h; + + adjusted_x = (*x - viewport.x) * scale_x; + adjusted_y = (*y - viewport.y) * scale_y; + + /* Clamp the result to the visible window */ + *x = SDL_max(SDL_min(adjusted_x, OpenGLLogicalScalingWidth), 0); + *y = SDL_max(SDL_min(adjusted_y, OpenGLLogicalScalingHeight), 0); +} + + static Uint8 MouseButtonState20to12(const Uint32 state20) { Uint8 retval = (state20 & 0x7); /* left, right, and middle will match. */ @@ -2512,6 +2575,7 @@ EventFilter20to12(void *data, SDL_Event *event20) event12.type = SDL12_MOUSEMOTION; event12.motion.which = (Uint8) event20->motion.which; event12.motion.state = event20->motion.state; + AdjustOpenGLLogicalScalingPoint(&event20->motion.x, &event20->motion.y); event12.motion.x = (Uint16) event20->motion.x; event12.motion.y = (Uint16) event20->motion.y; event12.motion.xrel = (Sint16) event20->motion.xrel; @@ -2543,6 +2607,7 @@ EventFilter20to12(void *data, SDL_Event *event20) event12.button.button += 2; /* SDL_BUTTON_X1/2 */ } event12.button.state = event20->button.state; + AdjustOpenGLLogicalScalingPoint(&event20->button.x, &event20->button.y); event12.button.x = (Uint16) event20->button.x; event12.button.y = (Uint16) event20->button.y; break; @@ -2555,6 +2620,7 @@ EventFilter20to12(void *data, SDL_Event *event20) event12.button.button += 2; /* SDL_BUTTON_X1/2 */ } event12.button.state = event20->button.state; + AdjustOpenGLLogicalScalingPoint(&event20->button.x, &event20->button.y); event12.button.x = (Uint16) event20->button.x; event12.button.y = (Uint16) event20->button.y; break; @@ -4378,6 +4444,7 @@ UpdateRelativeMouseMode(void) /* reset position, we'll have to track it ourselves in SDL_MOUSEMOTION events, since 1.2 * would give you window coordinates, even in relative mode. */ SDL20_GetMouseState(&MousePosition.x, &MousePosition.y); + AdjustOpenGLLogicalScalingPoint(&MousePosition.x, &MousePosition.y); } SDL20_SetRelativeMouseMode(MouseInputIsRelative); } @@ -4845,38 +4912,10 @@ SDL_GL_SwapBuffers(void) const char *scale_method_env = SDL20_getenv("SDL12COMPAT_SCALE_METHOD"); const SDL_bool want_nearest = (scale_method_env && !SDL20_strcmp(scale_method_env, "nearest"))? SDL_TRUE : SDL_FALSE; GLfloat clearcolor[4]; - float want_aspect, real_aspect; - int drawablew, drawableh; - SDL_Rect dstrect; + SDL_Rect dstrect = GetOpenGLLogicalScalingViewport(); - SDL20_GL_GetDrawableSize(VideoWindow20, &drawablew, &drawableh); OpenGLFuncs.glGetFloatv(GL_COLOR_CLEAR_VALUE, clearcolor); - want_aspect = ((float) OpenGLLogicalScalingWidth) / ((float) OpenGLLogicalScalingHeight); - real_aspect = ((float) drawablew) / ((float) drawableh); - - if (SDL20_fabsf(want_aspect-real_aspect) < 0.0001f) { - /* The aspect ratios are the same, just scale appropriately */ - dstrect.x = 0; - dstrect.y = 0; - dstrect.w = drawablew; - dstrect.h = drawableh; - } else if (want_aspect > real_aspect) { - /* We want a wider aspect ratio than is available - letterbox it */ - const float scale = ((float) drawablew) / OpenGLLogicalScalingWidth; - dstrect.x = 0; - dstrect.w = drawablew; - dstrect.h = (int)SDL20_floorf(OpenGLLogicalScalingHeight * scale); - dstrect.y = (drawableh - dstrect.h) / 2; - } else { - /* We want a narrower aspect ratio than is available - use side-bars */ - const float scale = ((float)drawableh) / OpenGLLogicalScalingHeight; - dstrect.y = 0; - dstrect.h = drawableh; - dstrect.w = (int)SDL20_floorf(OpenGLLogicalScalingWidth * scale); - dstrect.x = (drawablew - dstrect.w) / 2; - } - if (has_scissor) { OpenGLFuncs.glDisable(GL_SCISSOR_TEST); /* scissor test affects framebuffer_blit */ } From cc5826a7553ad850de1dfc1264128d9df6d44fa2 Mon Sep 17 00:00:00 2001 From: David Gow Date: Wed, 2 Jun 2021 16:03:16 +0800 Subject: [PATCH 013/606] Take DPI scaling into account when scaling mouse coordinates As mouse coordinates are in DPI-scaled units, but the drawable size (used for rendering) are physical pixel values, a different viewport and scaling factor are needed. Passing the "physical" size we expect to the GetOpenGLLogicalScalingViewport() lets us use the correct size (DPI-scaled or not) for each calculation. --- src/SDL12_compat.c | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index d318161ef..17d8d0405 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1902,37 +1902,38 @@ SDL_EventState(Uint8 type, int state) return retval; } +/* Calculates the Logical Scaling viewport based on a given window size. + We pass the DPI-unscaled pixel size in when using this for rendering, and + the DPI-scaled window size when using it to transform mouse coordinates. */ static SDL_Rect -GetOpenGLLogicalScalingViewport() +GetOpenGLLogicalScalingViewport(int physical_width, int physical_height) { float want_aspect, real_aspect; - int drawablew, drawableh; SDL_Rect dstrect; - SDL20_GL_GetDrawableSize(VideoWindow20, &drawablew, &drawableh); want_aspect = ((float) OpenGLLogicalScalingWidth) / ((float) OpenGLLogicalScalingHeight); - real_aspect = ((float) drawablew) / ((float) drawableh); + real_aspect = ((float) physical_width) / ((float) physical_height); if (SDL20_fabsf(want_aspect-real_aspect) < 0.0001f) { /* The aspect ratios are the same, just scale appropriately */ dstrect.x = 0; dstrect.y = 0; - dstrect.w = drawablew; - dstrect.h = drawableh; + dstrect.w = physical_width; + dstrect.h = physical_height; } else if (want_aspect > real_aspect) { /* We want a wider aspect ratio than is available - letterbox it */ - const float scale = ((float) drawablew) / OpenGLLogicalScalingWidth; + const float scale = ((float) physical_width) / OpenGLLogicalScalingWidth; dstrect.x = 0; - dstrect.w = drawablew; + dstrect.w = physical_width; dstrect.h = (int)SDL20_floorf(OpenGLLogicalScalingHeight * scale); - dstrect.y = (drawableh - dstrect.h) / 2; + dstrect.y = (physical_height - dstrect.h) / 2; } else { /* We want a narrower aspect ratio than is available - use side-bars */ - const float scale = ((float)drawableh) / OpenGLLogicalScalingHeight; + const float scale = ((float)physical_height) / OpenGLLogicalScalingHeight; dstrect.y = 0; - dstrect.h = drawableh; + dstrect.h = physical_height; dstrect.w = (int)SDL20_floorf(OpenGLLogicalScalingWidth * scale); - dstrect.x = (drawablew - dstrect.w) / 2; + dstrect.x = (physical_width - dstrect.w) / 2; } return dstrect; @@ -1942,6 +1943,7 @@ static void AdjustOpenGLLogicalScalingPoint(int *x, int *y) { SDL_Rect viewport; + int physical_w, physical_h; float scale_x, scale_y; int adjusted_x, adjusted_y; @@ -1950,8 +1952,9 @@ AdjustOpenGLLogicalScalingPoint(int *x, int *y) return; } - /* These will need to be scaled further if we want to support High-DPI */ - viewport = GetOpenGLLogicalScalingViewport(); + /* we want to scale based on the window size, which is dpi-scaled */ + SDL20_GetWindowSize(VideoWindow20, &physical_w, &physical_h); + viewport = GetOpenGLLogicalScalingViewport(physical_w, physical_h); scale_x = (float)OpenGLLogicalScalingWidth / viewport.w; scale_y = (float)OpenGLLogicalScalingHeight / viewport.h; @@ -4911,8 +4914,13 @@ SDL_GL_SwapBuffers(void) const GLboolean has_scissor = OpenGLFuncs.glIsEnabled(GL_SCISSOR_TEST); const char *scale_method_env = SDL20_getenv("SDL12COMPAT_SCALE_METHOD"); const SDL_bool want_nearest = (scale_method_env && !SDL20_strcmp(scale_method_env, "nearest"))? SDL_TRUE : SDL_FALSE; + int physical_w, physical_h; GLfloat clearcolor[4]; - SDL_Rect dstrect = GetOpenGLLogicalScalingViewport(); + SDL_Rect dstrect; + + /* use the drawable size, which is != window size for HIGHDPI systems */ + SDL20_GL_GetDrawableSize(VideoWindow20, &physical_w, &physical_h); + dstrect = GetOpenGLLogicalScalingViewport(physical_w, physical_h); OpenGLFuncs.glGetFloatv(GL_COLOR_CLEAR_VALUE, clearcolor); From 478d357a201cc442ff80e7f0515996e1bb8018ab Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 2 Jun 2021 22:30:31 -0400 Subject: [PATCH 014/606] Implemented SDL_OPENGLBLIT. This works a little differently than SDL 1.2, because we aren't trying to run this on a Voodoo 2 anymore. Instead of making a 256x256 texture and uploading/drawing in pieces to accomodate the small texture, we just make one texture the size of the window. It's easier and clearer (and I suspect probably faster than the upload/draw loop that 1.2 used). This also means your GL needs NPOT textures. Any GPU from the last 15 years should support this (either through an extension or being OpenGL >= 2.0). We don't bother trying to deal GL implementation without. This has only been tested with testgl -logoblit, because, as you should know: https://discourse.libsdl.org/t/for-all-who-search-a-sdl-openglblit-example/5376/2 --- src/SDL12_compat.c | 184 ++++++++++++++++++++++++++++++++++++++------- src/SDL20_syms.h | 27 +++++++ 2 files changed, 183 insertions(+), 28 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 17d8d0405..c24640fbe 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -815,6 +815,8 @@ static Uint8 KeyState[SDLK12_LAST]; static SDL_bool MouseInputIsRelative = SDL_FALSE; static SDL_Point MousePosition = { 0, 0 }; static OpenGLEntryPoints OpenGLFuncs; +static int OpenGLBlitLockCount = 0; +static GLuint OpenGLBlitTexture = 0; static int OpenGLLogicalScalingWidth = 0; static int OpenGLLogicalScalingHeight = 0; static GLuint OpenGLLogicalScalingFBO = 0; @@ -3273,6 +3275,10 @@ SetupScreenSaver(const int flags12) static SDL12_Surface * EndVidModeCreate(void) { + if (OpenGLBlitTexture) { + OpenGLFuncs.glDeleteTextures(1, &OpenGLBlitTexture); + OpenGLBlitTexture = 0; + } if (VideoTexture20) { SDL20_DestroyTexture(VideoTexture20); VideoTexture20 = NULL; @@ -3306,6 +3312,7 @@ EndVidModeCreate(void) } SDL_zero(OpenGLFuncs); + OpenGLBlitLockCount = 0; OpenGLLogicalScalingWidth = 0; OpenGLLogicalScalingHeight = 0; OpenGLLogicalScalingFBO = 0; @@ -3373,6 +3380,10 @@ LoadOpenGLFunctions(void) OpenGLFuncs.SUPPORTS_GL_ARB_framebuffer_object = SDL_TRUE; } + if (major >= 2) { + OpenGLFuncs.SUPPORTS_GL_ARB_texture_non_power_of_two = SDL_TRUE; /* core since 2.0 */ + } + /* load everything we can. */ #define OPENGL_SYM(ext,rc,fn,params,args,ret) OpenGLFuncs.fn = \ (OpenGLFuncs.SUPPORTS_##ext)? (openglfn_##fn##_t)SDL20_GL_GetProcAddress(#fn) : NULL; @@ -3609,12 +3620,6 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12) } } - if ((flags12 & SDL12_OPENGLBLIT) == SDL12_OPENGLBLIT) { - FIXME("No OPENGLBLIT support at the moment"); - SDL20_SetError("SDL_OPENGLBLIT is (currently) unsupported"); - return NULL; - } - FIXME("handle SDL_ANYFORMAT"); if ((width < 0) || (height < 0)) { @@ -3664,6 +3669,8 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12) SDL20_GL_DeleteContext(VideoGLContext20); VideoGLContext20 = NULL; SDL_zero(OpenGLFuncs); + OpenGLBlitTexture = 0; + OpenGLBlitLockCount = 0; OpenGLLogicalScalingWidth = 0; OpenGLLogicalScalingHeight = 0; OpenGLLogicalScalingFBO = 0; @@ -3766,6 +3773,30 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12) } } + if ((flags12 & SDL12_OPENGLBLIT) == SDL12_OPENGLBLIT) { + const int pixsize = VideoSurface12->format->BytesPerPixel; + const GLenum glfmt = (pixsize == 4) ? GL_RGBA : GL_RGB; + const GLenum gltype = (pixsize == 4) ? GL_UNSIGNED_BYTE : GL_UNSIGNED_SHORT_5_6_5; + + if (!OpenGLFuncs.SUPPORTS_GL_ARB_texture_non_power_of_two) { + SDL20_SetError("Your OpenGL drivers don't support NPOT textures for SDL_OPENGLBLIT; please upgrade."); + return EndVidModeCreate(); + } + + OpenGLFuncs.glGenTextures(1, &OpenGLBlitTexture); + OpenGLFuncs.glBindTexture(GL_TEXTURE_2D, OpenGLBlitTexture); + OpenGLFuncs.glTexImage2D(GL_TEXTURE_2D, 0, (pixsize == 4) ? GL_RGBA : GL_RGB, VideoSurface12->w, VideoSurface12->h, 0, glfmt, gltype, NULL); + + VideoSurface12->surface20->pixels = SDL20_malloc(height * VideoSurface12->pitch); + VideoSurface12->pixels = VideoSurface12->surface20->pixels; + if (!VideoSurface12->pixels) { + SDL20_OutOfMemory(); + return EndVidModeCreate(); + } + SDL20_memset(VideoSurface12->pixels, 0xFF, height * VideoSurface12->pitch); /* SDL 1.2 default OPENGLBLIT surface to full intensity */ + VideoSurface12->flags |= SDL12_OPENGLBLIT; + } + } else { /* always use a renderer for non-OpenGL windows. */ const char *vsync_env = SDL20_getenv("SDL12COMPAT_SYNC_TO_VBLANK"); @@ -4192,11 +4223,130 @@ UpdateRect12to20(SDL12_Surface *surface12, const SDL12_Rect *rect12, SDL_Rect *r } } +/* SDL_OPENGLBLIT support APIs. https://discourse.libsdl.org/t/ogl-and-sdl/2775/3 */ +DECLSPEC void SDLCALL +SDL_GL_Lock(void) +{ + if (!OpenGLBlitTexture) { + return; + } + + if (++OpenGLBlitLockCount == 1) { + OpenGLFuncs.glPushAttrib(GL_ALL_ATTRIB_BITS); + OpenGLFuncs.glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT); + OpenGLFuncs.glEnable(GL_TEXTURE_2D); + OpenGLFuncs.glEnable(GL_BLEND); + OpenGLFuncs.glDisable(GL_FOG); + OpenGLFuncs.glDisable(GL_ALPHA_TEST); + OpenGLFuncs.glDisable(GL_DEPTH_TEST); + OpenGLFuncs.glDisable(GL_SCISSOR_TEST); + OpenGLFuncs.glDisable(GL_STENCIL_TEST); + OpenGLFuncs.glDisable(GL_CULL_FACE); + + OpenGLFuncs.glBindTexture(GL_TEXTURE_2D, OpenGLBlitTexture); + OpenGLFuncs.glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + OpenGLFuncs.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + OpenGLFuncs.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + OpenGLFuncs.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + OpenGLFuncs.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + OpenGLFuncs.glPixelStorei(GL_UNPACK_ROW_LENGTH, VideoSurface12->pitch / VideoSurface12->format->BytesPerPixel); + OpenGLFuncs.glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + OpenGLFuncs.glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + + OpenGLFuncs.glViewport(0, 0, VideoSurface12->w, VideoSurface12->h); + OpenGLFuncs.glMatrixMode(GL_PROJECTION); + OpenGLFuncs.glPushMatrix(); + OpenGLFuncs.glLoadIdentity(); + + OpenGLFuncs.glOrtho(0.0, (GLdouble) VideoSurface12->w, (GLdouble) VideoSurface12->h, 0.0, 0.0, 1.0); + + OpenGLFuncs.glMatrixMode(GL_MODELVIEW); + OpenGLFuncs.glPushMatrix(); + OpenGLFuncs.glLoadIdentity(); + } +} + +DECLSPEC void SDLCALL +SDL_GL_UpdateRects(int numrects, SDL12_Rect *rects12) +{ + if (OpenGLBlitTexture) { + const int srcpitch = VideoSurface12->pitch; + const int pixsize = VideoSurface12->format->BytesPerPixel; + const GLenum glfmt = (pixsize == 4) ? GL_RGBA : GL_RGB; + const GLenum gltype = (pixsize == 4) ? GL_UNSIGNED_BYTE : GL_UNSIGNED_SHORT_5_6_5; + SDL_Rect surfacerect20; + int i; + + surfacerect20.x = surfacerect20.y = 0; + surfacerect20.w = VideoSurface12->w; + surfacerect20.h = VideoSurface12->h; + + for (i = 0; i < numrects; i++) { + SDL_Rect rect20; + SDL_Rect intersected20; + Uint8 *src; + + SDL20_IntersectRect(Rect12to20(&rects12[i], &rect20), &surfacerect20, &intersected20); + + src = (((Uint8 *) VideoSurface12->pixels) + (intersected20.y * srcpitch)) + (intersected20.x * pixsize); + OpenGLFuncs.glTexSubImage2D(GL_TEXTURE_2D, 0, intersected20.x, intersected20.y, intersected20.w, intersected20.h, glfmt, gltype, src); + + OpenGLFuncs.glBegin(GL_TRIANGLE_STRIP); + { + const GLfloat tex_x1 = ((GLfloat) intersected20.x) / ((GLfloat) VideoSurface12->w); + const GLfloat tex_y1 = ((GLfloat) intersected20.y) / ((GLfloat) VideoSurface12->h); + const GLfloat tex_x2 = tex_x1 + ((GLfloat) intersected20.w) / ((GLfloat) VideoSurface12->w); + const GLfloat tex_y2 = tex_y1 + ((GLfloat) intersected20.h) / ((GLfloat) VideoSurface12->h); + const GLint vert_x1 = (GLint) intersected20.x; + const GLint vert_y1 = (GLint) intersected20.y; + const GLint vert_x2 = vert_x1 + (GLint) intersected20.w; + const GLint vert_y2 = vert_y1 + (GLint) intersected20.h; + OpenGLFuncs.glTexCoord2f(tex_x1, tex_y1); + OpenGLFuncs.glVertex2i(vert_x1, vert_y1); + OpenGLFuncs.glTexCoord2f(tex_x2, tex_y1); + OpenGLFuncs.glVertex2i(vert_x2, vert_y1); + OpenGLFuncs.glTexCoord2f(tex_x1, tex_y2); + OpenGLFuncs.glVertex2i(vert_x1, vert_y2); + OpenGLFuncs.glTexCoord2f(tex_x2, tex_y2); + OpenGLFuncs.glVertex2i(vert_x2, vert_y2); + } + OpenGLFuncs.glEnd(); + } + } +} + + +DECLSPEC void SDLCALL +SDL_GL_Unlock(void) +{ + if (OpenGLBlitTexture) { + if (OpenGLBlitLockCount > 0) { + if (--OpenGLBlitLockCount == 0) { + OpenGLFuncs.glPopMatrix(); + OpenGLFuncs.glMatrixMode(GL_PROJECTION); + OpenGLFuncs.glPopMatrix(); + OpenGLFuncs.glPopClientAttrib(); + OpenGLFuncs.glPopAttrib(); + } + } + } +} + + DECLSPEC void SDLCALL SDL_UpdateRects(SDL12_Surface *surface12, int numrects, SDL12_Rect *rects12) { /* strangely, SDL 1.2 doesn't check if surface12 is NULL before touching it */ /* (UpdateRect, singular, does...) */ + + if ((surface12 == VideoSurface12) && ((surface12->flags & SDL12_OPENGLBLIT) == SDL12_OPENGLBLIT)) { + SDL_GL_Lock(); + SDL_GL_UpdateRects(numrects, rects12); + SDL_GL_Unlock(); + return; + } + if (surface12->flags & SDL12_OPENGL) { SDL20_SetError("Use SDL_GL_SwapBuffers() on OpenGL surfaces"); return; @@ -5621,28 +5771,6 @@ SDL_CloseAudio(void) } -/* !!! FIXME: these are just stubs for now, but Sam thinks that maybe these -were added at Loki for Heavy Gear 2's UI. They just make GL calls. */ -DECLSPEC void SDLCALL -SDL_GL_Lock(void) -{ - FIXME("write me"); -} - -DECLSPEC void SDLCALL -SDL_GL_UpdateRects(int numrects, SDL12_Rect *rects) -{ - (void) numrects; - (void) rects; - FIXME("write me"); -} - -DECLSPEC void SDLCALL -SDL_GL_Unlock(void) -{ - FIXME("write me"); -} - /* SDL_GL_DisableContext and SDL_GL_EnableContext_Thread are not real SDL 1.2 APIs, but some idTech4 games shipped with a custom SDL 1.2 build that added diff --git a/src/SDL20_syms.h b/src/SDL20_syms.h index 1f964e625..29b1007e9 100644 --- a/src/SDL20_syms.h +++ b/src/SDL20_syms.h @@ -329,6 +329,31 @@ OPENGL_SYM(Core,void,glCopyTexImage2D,(GLenum a, GLint b, GLenum c, GLint d, GLi OPENGL_SYM(Core,void,glCopyTexSubImage2D,(GLenum a, GLint b, GLint c, GLint d, GLint e, GLint f, GLsizei g, GLsizei h),(a,b,c,d,e,f,g,h),) OPENGL_SYM(Core,void,glCopyTexSubImage3D,(GLenum a, GLint b, GLint c, GLint d, GLint e, GLint f, GLsizei g, GLsizei h, GLint i),(a,b,c,d,e,f,g,h,i),) +OPENGL_SYM(Core,void,glDeleteTextures,(GLsizei a, const GLuint *b),(a,b),) +OPENGL_SYM(Core,void,glGenTextures,(GLsizei a, GLuint *b),(a,b),) +OPENGL_SYM(Core,void,glPopAttrib,(),(),) +OPENGL_SYM(Core,void,glPopClientAttrib,(),(),) +OPENGL_SYM(Core,void,glPopMatrix,(),(),) +OPENGL_SYM(Core,void,glBegin,(GLenum a),(a),) +OPENGL_SYM(Core,void,glPushAttrib,(GLbitfield a),(a),) +OPENGL_SYM(Core,void,glPushClientAttrib,(GLbitfield a),(a),) +OPENGL_SYM(Core,void,glBindTexture,(GLenum a, GLuint b),(a,b),) +OPENGL_SYM(Core,void,glEnd,(),(),) +OPENGL_SYM(Core,void,glTexEnvf,(GLenum a, GLenum b, GLfloat c),(a,b,c),) +OPENGL_SYM(Core,void,glTexParameteri,(GLenum a, GLenum b, GLint c),(a,b,c),) +OPENGL_SYM(Core,void,glPixelStorei,(GLenum a, GLint b),(a,b),) +OPENGL_SYM(Core,void,glBlendFunc,(GLenum a, GLenum b),(a,b),) +OPENGL_SYM(Core,void,glColor4f,(GLfloat a, GLfloat b, GLfloat c, GLfloat d),(a,b,c,d),) +OPENGL_SYM(Core,void,glMatrixMode,(GLenum a),(a),) +OPENGL_SYM(Core,void,glLoadIdentity,(),(),) +OPENGL_SYM(Core,void,glPushMatrix,(),(),) +OPENGL_SYM(Core,void,glOrtho,(GLdouble a, GLdouble b, GLdouble c, GLdouble d, GLdouble e, GLdouble f),(a,b,c,d,e,f),) +OPENGL_SYM(Core,void,glTexImage2D,(GLenum a, GLint b, GLint c, GLsizei d, GLsizei e, GLint f, GLenum g, GLenum h, const GLvoid *i),(a,b,c,d,e,f,g,h,i),) +OPENGL_SYM(Core,void,glTexSubImage2D,(GLenum a, GLint b, GLint c, GLint d, GLsizei e, GLsizei f, GLenum g, GLenum h, const GLvoid *i),(a,b,c,d,e,f,g,h,i),) +OPENGL_SYM(Core,void,glVertex2i,(GLint a, GLint b),(a,b),) +OPENGL_SYM(Core,void,glTexCoord2f,(GLfloat a, GLfloat b),(a,b),) + + OPENGL_EXT(GL_ARB_framebuffer_object) OPENGL_SYM(GL_ARB_framebuffer_object,void,glBindRenderbuffer,(GLenum a, GLuint b),(a,b),) OPENGL_SYM(GL_ARB_framebuffer_object,void,glDeleteRenderbuffers,(GLsizei a, const GLuint *b),(a,b),) @@ -344,6 +369,8 @@ OPENGL_SYM(GL_ARB_framebuffer_object,GLenum,glCheckFramebufferStatus,(GLenum a), OPENGL_SYM(GL_ARB_framebuffer_object,void,glFramebufferRenderbuffer,(GLenum a, GLenum b, GLenum c, GLuint d),(a,b,c,d),) OPENGL_SYM(GL_ARB_framebuffer_object,void,glBlitFramebuffer,(GLint a, GLint b, GLint c, GLint d, GLint e, GLint f, GLint g, GLint h, GLbitfield i, GLenum j),(a,b,c,d,e,f,g,h,i,j),) +OPENGL_EXT(GL_ARB_texture_non_power_of_two) + #undef SDL20_SYM #undef SDL20_SYM_PASSTHROUGH #undef SDL20_SYM_VARARGS From 012e2efff9b7941759abc2c68a1dd1f337829338 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 2 Jun 2021 22:41:03 -0400 Subject: [PATCH 015/606] Hook up SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, ...) --- src/SDL12_compat.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index c24640fbe..258397e0a 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -3797,6 +3797,8 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12) VideoSurface12->flags |= SDL12_OPENGLBLIT; } + SDL20_GL_SetSwapInterval(SwapInterval); + } else { /* always use a renderer for non-OpenGL windows. */ const char *vsync_env = SDL20_getenv("SDL12COMPAT_SYNC_TO_VBLANK"); From 0c2c8d6e5173bae89997dd5207eab877ed086621 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 3 Jun 2021 15:36:21 -0400 Subject: [PATCH 016/606] OpenGL logical scaling: specify a stencil attachment. Corrects wrong object glow rendering in Psychonauts. Fixes #62. --- src/SDL12_compat.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 258397e0a..02a5170fd 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -3525,6 +3525,7 @@ InitializeOpenGLScaling(const int w, const int h) OpenGLFuncs.glBindRenderbuffer(GL_RENDERBUFFER, OpenGLLogicalScalingDepth); OpenGLFuncs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, OpenGLLogicalScalingSamples, GL_DEPTH24_STENCIL8, w, h); OpenGLFuncs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, OpenGLLogicalScalingDepth); + OpenGLFuncs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, OpenGLLogicalScalingDepth); OpenGLFuncs.glBindRenderbuffer(GL_RENDERBUFFER, 0); if ( (OpenGLFuncs.glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) || OpenGLFuncs.glGetError() ) { @@ -3545,8 +3546,9 @@ InitializeOpenGLScaling(const int w, const int h) OpenGLFuncs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, OpenGLLogicalScalingMultisampleColor); OpenGLFuncs.glGenRenderbuffers(1, &OpenGLLogicalScalingMultisampleDepth); OpenGLFuncs.glBindRenderbuffer(GL_RENDERBUFFER, OpenGLLogicalScalingMultisampleDepth); - OpenGLFuncs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, w, h); /* !!! FIXME: is an extension (or core 3.0) */ + OpenGLFuncs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, w, h); FIXME("is an extension (or core 3.0)?"); OpenGLFuncs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, OpenGLLogicalScalingMultisampleDepth); + OpenGLFuncs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, OpenGLLogicalScalingMultisampleDepth); OpenGLFuncs.glBindRenderbuffer(GL_RENDERBUFFER, 0); if ( (OpenGLFuncs.glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) || OpenGLFuncs.glGetError() ) { From f6a60d6534a16308cfc22f7b0945797849efb083 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Fri, 4 Jun 2021 02:10:20 +0300 Subject: [PATCH 017/606] Makefile.linux, Makefile.darwin: create missing libSDL.so symlinks. --- src/Makefile.darwin | 3 ++- src/Makefile.linux | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Makefile.darwin b/src/Makefile.darwin index acac1a5ca..019448e12 100644 --- a/src/Makefile.darwin +++ b/src/Makefile.darwin @@ -33,12 +33,13 @@ all: $(DYLIB) $(DYLIB): $(OBJ) $(LD) -o $@ $(LDFLAGS) $(OBJ) $(LDLIBS) + ln -s $(DYLIB) libSDL.dylib .c.o: $(CC) $(CFLAGS) $(CPPFLAGS) $(INCLUDES) -o $@ -c $< .m.o: $(CC) $(CFLAGS) $(CPPFLAGS) $(INCLUDES) -o $@ -c $< distclean: clean - $(RM) $(DYLIB) + $(RM) *.dylib clean: $(RM) *.o diff --git a/src/Makefile.linux b/src/Makefile.linux index 0f5d85973..f85ca96c2 100644 --- a/src/Makefile.linux +++ b/src/Makefile.linux @@ -28,6 +28,7 @@ $(SHLIB): $(OBJ) $(LD) -o $@ $(LDFLAGS) $(OBJ) $(LDLIBS) ln -s $(SHLIB) libSDL-1.2.so ln -s $(SHLIB) libSDL-1.2.so.0 + ln -s $(SHLIB) libSDL.so .c.o: $(CC) $(CFLAGS) $(CPPFLAGS) $(INCLUDES) -o $@ -c $< From 32c55713feddca619904486488b772baa58a1620 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Mon, 7 Jun 2021 01:08:02 +0300 Subject: [PATCH 018/606] include/SDL/SDL_platform.h: dropped Mac OS X target >= 10.6 requirement. --- include/SDL/SDL_platform.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/include/SDL/SDL_platform.h b/include/SDL/SDL_platform.h index 5e6424575..4eea24dba 100644 --- a/include/SDL/SDL_platform.h +++ b/include/SDL/SDL_platform.h @@ -27,7 +27,8 @@ real SDL-1.2 available to you. */ #define SDL_platform_h_ /* this was taken from SDL2's zlib-licensed headers. This drops BeOS (not Haiku) -and MacOS Classic, but SDL2 doesn't run on them anyhow. Send patches. :) */ +and MacOS Classic, but SDL2 doesn't run on them anyhow. Mac OS X target >= 10.6 +requirement is dropped too. Send patches. :) */ #if defined(_AIX) #undef __AIX__ @@ -84,9 +85,6 @@ and MacOS Classic, but SDL2 doesn't run on them anyhow. Send patches. :) */ /* if not compiling for iOS */ #undef __MACOSX__ #define __MACOSX__ 1 -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 -# error SDL for Mac OS X only supports deploying on 10.6 and above. -#endif /* MAC_OS_X_VERSION_MIN_REQUIRED < 1060 */ #endif /* TARGET_OS_IPHONE */ #endif /* defined(__APPLE__) */ From 8d84adcc4d1cbc2463a33dd38eba32ae5e3895a2 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Mon, 7 Jun 2021 01:10:10 +0300 Subject: [PATCH 019/606] test/testcdrom.c: silenced a 'used uninitialized' warning. --- test/testcdrom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/testcdrom.c b/test/testcdrom.c index 782a66cc3..2fc6daeb9 100644 --- a/test/testcdrom.c +++ b/test/testcdrom.c @@ -17,8 +17,8 @@ static void quit(int rc) static void PrintStatus(int driveindex, SDL_CD *cdrom) { + const char *status_str = "unknown"; CDstatus status; - char *status_str; status = SDL_CDStatus(cdrom); switch (status) { From ba4c1749d2e846f91886f37cbc9306003013662d Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Mon, 7 Jun 2021 14:29:10 +0300 Subject: [PATCH 020/606] cmake: make dylib versions overridable (thanks Dominik Reichardt.) --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6256c3a06..2231d1a10 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,8 +18,8 @@ if(APPLE) set(OSX_SRCS "src/SDL12_compat_objc.m") set_source_files_properties(${OSX_SRCS} PROPERTIES LANGUAGE C) # the following matches SDL-1.2 Xcode project file - set(DYLIB_COMPAT_VERSION 1.0.0) - set(DYLIB_CURRENT_VERSION 12.50.0) + set(DYLIB_COMPAT_VERSION 1.0.0 CACHE STRING "library compatibility version") + set(DYLIB_CURRENT_VERSION 12.50.0 CACHE STRING "library current version") include_directories("/opt/X11/include") # hack. endif() if(WIN32) From e5a32aa721c54874ee074c4edac18c746518d5ff Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 7 Jun 2021 15:11:13 -0400 Subject: [PATCH 021/606] cdrom: implemented fake CD-ROM support. This makes a directory of MP3 files look like an audio CD to the 1.2 app, so something like (for example) Quake 1 can rip the retail disc's audio to the filesystem, and an SDL 1.2 version of the game will still believe the soundtrack is playing from disc. This requires us to share the audio device with the 1.2 SDL_OpenAudio interface, which presents some other tapdancing, but it appears to be a feasible approach. Fixes #32. --- LICENSE.txt | 4 + src/SDL12_compat.c | 993 ++++++++- src/SDL20_syms.h | 20 +- src/dr_mp3.h | 4750 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 5669 insertions(+), 98 deletions(-) create mode 100644 src/dr_mp3.h diff --git a/LICENSE.txt b/LICENSE.txt index 969b8c13d..579141f03 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -16,3 +16,7 @@ freely, subject to the following restrictions: misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. + + +This project includes code from dr_mp3 ( https://github.com/mackron/dr_libs ) +which can be treated as public domain or MIT-0 licensed, at your option. \ No newline at end of file diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 02a5170fd..7b72fce21 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -747,6 +747,34 @@ typedef enum } SDL12_GLattr; +typedef enum +{ + SDL12_CD_TRAYEMPTY, + SDL12_CD_STOPPED, + SDL12_CD_PLAYING, + SDL12_CD_PAUSED, + SDL12_CD_ERROR = -1 +} SDL12_CDstatus; + +typedef struct +{ + Uint8 id; + Uint8 type; + Uint16 unused; + Uint32 length; + Uint32 offset; +} SDL12_CDtrack; + +typedef struct SDL12_CD +{ + int id; + SDL12_CDstatus status; + int numtracks; + int cur_track; + int cur_frame; + SDL12_CDtrack track[100]; /* in 1.2, this was SDL_MAX_TRACKS+1 */ +} SDL12_CD; + typedef struct { Uint32 format; @@ -805,7 +833,9 @@ static char *WindowIconTitle = NULL; static SDL_Surface *VideoIcon20 = NULL; static int EnabledUnicode = 0; static int VideoDisplayIndex = 0; -static int CDRomInit = 0; +static SDL_bool CDRomInit = SDL_FALSE; +static char *CDRomPath = NULL; +static SDL12_CD *CDRomDevice = NULL; static SDL12_EventFilter EventFilter12 = NULL; static SDL12_Cursor *CurrentCursor12 = NULL; static Uint8 EventStates[SDL12_NUMEVENTS]; @@ -853,6 +883,7 @@ static char loaderror[256]; #define WIN32_LEAN_AND_MEAN 1 #endif #include + #define DIRSEP "\\" #define SDL20_LIBNAME "SDL2.dll" /* require SDL2 >= 2.0.12 for SDL_CreateThread binary compatibility */ #define SDL20_REQUIRED_VER SDL_VERSIONNUM(2,0,12) @@ -864,6 +895,7 @@ static char loaderror[256]; #define sprintf_fn wsprintfA #elif defined(__OS2__) #include + #define DIRSEP "\\" #define SDL20_LIBNAME "SDL2.dll" #define SDL20_REQUIRED_VER SDL_VERSIONNUM(2,0,9) #define strcpy_fn strcpy @@ -955,6 +987,11 @@ static char loaderror[256]; #error Please define your platform. #endif +#ifndef DIRSEP +#define DIRSEP "/" +#endif + + static void * LoadSDL20Symbol(const char *fn, int *okay) { @@ -1538,6 +1575,11 @@ SDL_VideoInit(const char *driver, Uint32 flags) return SDL20_VideoInit(driver); } + +static void InitializeCDSubsystem(void); +static void QuitCDSubsystem(void); + + DECLSPEC int SDLCALL SDL_InitSubSystem(Uint32 sdl12flags) { @@ -1558,9 +1600,11 @@ SDL_InitSubSystem(Uint32 sdl12flags) SETFLAG(NOPARACHUTE); #undef SETFLAG - /* There's no CDROM in 2.0, but we'll just pretend it succeeded. */ - if (sdl12flags & SDL12_INIT_CDROM) - CDRomInit = 1; + /* There's no CDROM in 2.0, but we fake it. */ + if (sdl12flags & SDL12_INIT_CDROM) { + /* this never reports failure, even if there's a legit problem. You just won't see any drives. */ + InitializeCDSubsystem(); + } rc = SDL20_Init(sdl20flags); if ((rc == 0) && (sdl20flags & SDL_INIT_VIDEO)) { @@ -1663,7 +1707,7 @@ SDL_QuitSubSystem(Uint32 sdl12flags) InitFlags12To20(sdl12flags, &sdl20flags, &extraflags); if (extraflags & SDL12_INIT_CDROM) { - CDRomInit = 0; + QuitCDSubsystem(); } if (sdl12flags & SDL12_INIT_VIDEO) { @@ -5238,66 +5282,6 @@ SDL_putenv(const char *_var) } -/* CD-ROM support is gone from SDL 2.0, so just have stubs that fail. */ - -typedef void *SDL12_CD; /* close enough. :) */ -typedef int SDL12_CDstatus; /* close enough. :) */ - -DECLSPEC int SDLCALL -SDL_CDNumDrives(void) -{ - FIXME("should return -1 without SDL_INIT_CDROM"); - return 0; -} - -DECLSPEC const char *SDLCALL SDL_CDName(int drive) { - SDL20_Unsupported(); - (void)drive; - return NULL; -} -DECLSPEC SDL12_CD *SDLCALL SDL_CDOpen(int drive) { - SDL20_Unsupported(); - (void)drive; - return NULL; -} -DECLSPEC SDL12_CDstatus SDLCALL SDL_CDStatus(SDL12_CD *cdrom) { - (void) cdrom; - return SDL20_Unsupported(); -} -DECLSPEC int SDLCALL SDL_CDPlayTracks(SDL12_CD *cdrom, int start_track, int start_frame, int ntracks, int nframes) { - (void) cdrom; - (void) start_track; - (void) start_frame; - (void) ntracks; - (void) nframes; - return SDL20_Unsupported(); -} -DECLSPEC int SDLCALL SDL_CDPlay(SDL12_CD *cdrom, int start, int length) { - (void) cdrom; - (void) start; - (void) length; - return SDL20_Unsupported(); -} -DECLSPEC int SDLCALL SDL_CDPause(SDL12_CD *cdrom) { - (void) cdrom; - return SDL20_Unsupported(); -} -DECLSPEC int SDLCALL SDL_CDResume(SDL12_CD *cdrom) { - (void) cdrom; - return SDL20_Unsupported(); -} -DECLSPEC int SDLCALL SDL_CDStop(SDL12_CD *cdrom) { - (void) cdrom; - return SDL20_Unsupported(); -} -DECLSPEC int SDLCALL SDL_CDEject(SDL12_CD *cdrom) { - (void) cdrom; - return SDL20_Unsupported(); -} -DECLSPEC void SDLCALL SDL_CDClose(SDL12_CD *cdrom) { - (void) cdrom; -} - #if (defined(_WIN32) || defined(__OS2__)) && !defined(SDL_PASSED_BEGINTHREAD_ENDTHREAD) #error SDL_PASSED_BEGINTHREAD_ENDTHREAD not defined #endif @@ -5693,45 +5677,818 @@ SDL_LoadWAV_RW(SDL12_RWops *rwops12, int freerwops12, return retval; } + +/* CD-ROM API! + We don't support physical CD drives in sdl12-compat. In modern times, it's + hard to find discs at all, let alone discs with audio tracks. Drives are + also getting scarce, and ones that are plugged into the sound output + hardware moreso. With this in mind, sdl12-compat can be instructed to + point to a filesystem directory full .mp3 files, and will pretend this is + an audio CD-ROM, and will decode these files and mix them into an audio + stream as if they were playing from a disc. */ + +#define CDAUDIO_FPS 75 /* CD audio frames per second. */ + +/* public domain, single-header MP3 decoder for fake CD-ROM audio support! */ +#define DR_MP3_IMPLEMENTATION +#define DR_MP3_NO_STDIO 1 +#define DR_MP3_FLOAT_OUTPUT 1 +#define DRMP3_ASSERT(x) SDL_assert((x)) +#define DRMP3_MALLOC(sz) SDL20_malloc((sz)) +#define DRMP3_REALLOC(p, sz) SDL20_realloc((p), (sz)) +#define DRMP3_FREE(p) SDL20_free((p)) +#define DRMP3_COPY_MEMORY(dst, src, sz) SDL20_memcpy((dst), (src), (sz)) +#define DRMP3_ZERO_MEMORY(p, sz) SDL20_memset((p), 0, (sz)) + +#if !defined(__clang_analyzer__) +#ifdef memset +#undef memset +#endif +#ifdef memcpy +#undef memcpy +#endif +#ifdef memmove +#undef memmove +#endif +#define memset SDL20_memset +#define memcpy SDL20_memcpy +#define memmove SDL20_memmove +#endif + +#include "dr_mp3.h" + +static size_t +mp3_sdlrwops_read(void *data, void *buf, size_t bytesToRead) +{ + return SDL20_RWread((SDL_RWops *) data, buf, 1, bytesToRead); +} + +static drmp3_bool32 +mp3_sdlrwops_seek(void *data, int offset, drmp3_seek_origin origin) +{ + const int whence = (origin == drmp3_seek_origin_start) ? RW_SEEK_SET : RW_SEEK_CUR; + SDL_assert((origin == drmp3_seek_origin_start) || (origin == drmp3_seek_origin_current)); + return (SDL20_RWseek((SDL_RWops *) data, offset, whence) == -1) ? DRMP3_FALSE : DRMP3_TRUE; +} + + +static int OpenSDL2AudioDevice(SDL_AudioSpec *); +static void CloseSDL2AudioDevice(void); +static SDL_bool ResetAudioStream(SDL_AudioStream **_stream, SDL_AudioSpec *spec, const SDL_AudioSpec *to, const SDL_AudioFormat fromfmt, const Uint8 fromchannels, const int fromfreq); + typedef struct { - void (SDLCALL *app_callback)(void *userdata, Uint8 *stream, int len); - void *app_userdata; - Uint8 silence; + SDL_AudioSpec device_format; + + SDL_bool app_callback_opened; + SDL_bool app_callback_paused; + SDL_AudioSpec app_callback_format; + SDL_AudioStream *app_callback_stream; + + SDL_bool cdrom_opened; + SDL_AudioSpec cdrom_format; + SDL_AudioStream *cdrom_stream; + + SDL12_CDstatus cdrom_status; + int cdrom_pcm_frames_written; + int cdrom_cur_track; + int cdrom_cur_frame; + int cdrom_stop_ntracks; + int cdrom_stop_nframes; + drmp3 cdrom_mp3; + + Uint8 *mix_buffer; + size_t mixbuflen; } AudioCallbackWrapperData; static AudioCallbackWrapperData *audio_cbdata = NULL; + + +static void +FreeMp3(drmp3 *mp3) +{ + SDL_RWops *rw = (SDL_RWops *) mp3->pUserData; + if (rw) { + drmp3_uninit(mp3); + mp3->pUserData = NULL; + SDL20_RWclose(rw); + } +} + + +static SDL_bool +CDSubsystemIsInitialized(void) +{ + if (!CDRomInit) { + SDL20_SetError("CD-ROM subsystem not initialized"); + return SDL_FALSE; + } + return SDL_TRUE; +} + +/* This never reports failure; if there's a problem, we report zero drives found. */ +static void +InitializeCDSubsystem(void) +{ + const char *cdpath; + + FIXME("Is subsystem init reference counted in SDL 1.2?"); /* it is in SDL2, but I don't know for 1.2. */ + if (CDRomInit) { + return; + } + + cdpath = SDL20_getenv("SDL12COMPAT_FAKE_CDROM_PATH"); + if (cdpath) { + CDRomPath = SDL_strdup(cdpath); + } + + CDRomInit = SDL_TRUE; +} + +static void +QuitCDSubsystem(void) +{ + if (!CDRomInit) { + return; + } + SDL_free(CDRomPath); + CDRomPath = NULL; + CDRomInit = SDL_FALSE; +} + +DECLSPEC int SDLCALL +SDL_CDNumDrives(void) +{ + if (!CDSubsystemIsInitialized()) { + return -1; + } + + if (!CDRomPath) { + static SDL_bool warned_once = SDL_FALSE; + if (!warned_once) { + warned_once = SDL_TRUE; + SDL20_Log("This app is looking for CD-ROM drives, but no path was specified"); + SDL20_Log("Set the SDL12COMPAT_FAKE_CDROM_PATH environment variable to a directory"); + SDL20_Log("of MP3 files named NUM.mp3, where NUM is a track number from 0 to 99"); + } + } + + return CDRomPath ? 1 : 0; +} + +static SDL_bool +ValidCDDriveIndex(const int drive) +{ + if (!CDSubsystemIsInitialized()) { + return SDL_FALSE; + } + + if (!CDRomPath || (drive != 0)) { + SDL_SetError("Invalid CD-ROM drive index"); + return SDL_FALSE; + } + + return SDL_TRUE; +} + +DECLSPEC const char * SDLCALL +SDL_CDName(int drive) +{ + return ValidCDDriveIndex(drive) ? CDRomPath : NULL; +} + +DECLSPEC SDL12_CD * SDLCALL +SDL_CDOpen(int drive) +{ + SDL12_CD *retval; + size_t alloclen; + char *fullpath; + Uint32 total_track_offset = 0; + + if (!ValidCDDriveIndex(drive)) { + return NULL; + } + + retval = (SDL12_CD *) SDL20_calloc(1, sizeof(SDL12_CD)); + if (!retval) { + SDL20_OutOfMemory(); + return NULL; + } + + alloclen = SDL20_strlen(CDRomPath) + 32; + fullpath = (char *) SDL20_malloc(alloclen); + if (fullpath == NULL) { + SDL20_free(retval); + SDL20_OutOfMemory(); + return NULL; + } + + /* We should probably do a proper enumeration of this directory, + but that needs platform-specific code that SDL2 doesn't offer. + readdir() is surprisingly hard to do without a bunch of different + platform backends! We just open files until we fail to do so, + and then stop. */ + FIXME("Can we do something more robust than this for directory enumeration?"); + for (;;) { + SDL_RWops *rw; + drmp3 mp3; + drmp3_uint64 pcmframes; + drmp3_uint32 samplerate; + SDL12_CDtrack *track; + + /* we only report audio tracks, starting at 0... */ + FIXME("Let there be fake data tracks (quake1's audio starts at track 2, etc)."); + SDL20_snprintf(fullpath, alloclen, "%s%s%d.mp3", CDRomPath, DIRSEP, retval->numtracks); + rw = SDL20_RWFromFile(fullpath, "rb"); + if (!rw) { + break; /* ok, we're done looking for more. */ + } + + if (!drmp3_init(&mp3, mp3_sdlrwops_read, mp3_sdlrwops_seek, rw, NULL)) { + SDL20_RWclose(rw); + break; /* ok, we're done looking for more. */ + } + + pcmframes = drmp3_get_pcm_frame_count(&mp3); + samplerate = mp3.sampleRate; + FreeMp3(&mp3); + + track = &retval->track[retval->numtracks]; + track->id = retval->numtracks; + track->type = 0; /* audio track. Data tracks are 4. */ + track->length = (Uint32) ((((double) pcmframes) / ((double) samplerate)) * CDAUDIO_FPS); + track->offset = total_track_offset; + total_track_offset += track->length; + + retval->numtracks++; + + if (retval->numtracks == 99) { + break; /* max tracks you can have on an audio CD. */ + } + } + SDL20_free(fullpath); + + retval->id = 1; /* just to be non-zero, I guess. */ + retval->status = (retval->numtracks > 0) ? SDL12_CD_STOPPED : SDL12_CD_TRAYEMPTY; + + if (retval->numtracks > 0) { + SDL_AudioSpec want; + SDL_zero(want); + want.freq = 44100; + want.format = AUDIO_F32SYS; + want.channels = 2; + want.samples = 4096; + + if (!OpenSDL2AudioDevice(&want)) { + retval->numtracks = 0; + retval->status = SDL12_CD_TRAYEMPTY; + } else { + /* Device is locked now, even if was opened and playing before. Set up some things. */ + SDL20_memcpy(&audio_cbdata->cdrom_format, &want, sizeof (SDL_AudioSpec)); + audio_cbdata->cdrom_opened = SDL_TRUE; + audio_cbdata->cdrom_status = SDL12_CD_STOPPED; + audio_cbdata->cdrom_pcm_frames_written = 0; + audio_cbdata->cdrom_cur_track = 0; + audio_cbdata->cdrom_cur_frame = 0; + SDL20_UnlockAudio(); + } + } + + CDRomDevice = retval; /* NULL API args use the last opened device. */ + + return retval; +} + +static SDL12_CD * +ValidCDDevice(SDL12_CD *cdrom) +{ + if (!CDSubsystemIsInitialized()) { + return NULL; + } else if (!cdrom) { + if (!CDRomDevice) { + SDL20_SetError("CD-ROM not opened"); + } else { + cdrom = CDRomDevice; + } + } + return cdrom; +} + + +DECLSPEC SDL12_CDstatus SDLCALL +SDL_CDStatus(SDL12_CD *cdrom) +{ + SDL12_CDstatus retval; + + if ((cdrom = ValidCDDevice(cdrom)) == NULL) { + return SDL12_CD_ERROR; + } + + SDL20_LockAudio(); /* we update this during the audio callback. */ + if (audio_cbdata) { + cdrom->status = audio_cbdata->cdrom_status; + cdrom->cur_track = audio_cbdata->cdrom_cur_track; + cdrom->cur_frame = audio_cbdata->cdrom_cur_frame; + } + retval = cdrom->status; + SDL20_UnlockAudio(); + + return retval; +} + +static SDL_bool +LoadCDTrack(const int tracknum, drmp3 *mp3) +{ + const SDL_AudioSpec *have = &audio_cbdata->device_format; + SDL_RWops *rw = NULL; + const size_t alloclen = SDL20_strlen(CDRomPath) + 32; + char *fullpath = (char *) SDL_malloc(alloclen); + + if (!fullpath) { + return SDL_FALSE; + } + + SDL20_snprintf(fullpath, alloclen, "%s%s%d.mp3", CDRomPath, DIRSEP, tracknum); + rw = SDL20_RWFromFile(fullpath, "rb"); + SDL20_free(fullpath); + + if (!rw) { + return SDL_FALSE; + } + + if (!drmp3_init(mp3, mp3_sdlrwops_read, mp3_sdlrwops_seek, rw, NULL)) { + SDL20_RWclose(rw); + return SDL_FALSE; + } + + if (!ResetAudioStream(&audio_cbdata->cdrom_stream, &audio_cbdata->cdrom_format, have, AUDIO_F32SYS, mp3->channels, mp3->sampleRate)) { + FreeMp3(mp3); + return SDL_FALSE; + } + + return SDL_TRUE; +} + +static int +StartCDAudioPlaying(SDL12_CD *cdrom, const int start_track, const int start_frame, const int ntracks, const int nframes) +{ + drmp3 mp3; + const SDL_bool loaded = LoadCDTrack(start_track, &mp3); + const SDL_bool seeking = loaded && (start_frame > 0); + const drmp3_uint64 pcm_frame = seeking ? ((drmp3_uint64) ((start_frame / 75.0) * mp3.sampleRate)) : 0; + + if (seeking) { /* do seeking before handing off to the audio thread. */ + drmp3_seek_to_pcm_frame(&mp3, pcm_frame); + } + + SDL20_LockAudio(); + if (audio_cbdata) { + cdrom->status = audio_cbdata->cdrom_status = loaded ? SDL12_CD_PLAYING : SDL12_CD_TRAYEMPTY; + audio_cbdata->cdrom_pcm_frames_written = (int) pcm_frame; + audio_cbdata->cdrom_cur_track = start_track; + audio_cbdata->cdrom_cur_frame = start_frame; + audio_cbdata->cdrom_stop_ntracks = ntracks; + audio_cbdata->cdrom_stop_nframes = nframes; + FreeMp3(&audio_cbdata->cdrom_mp3); + if (loaded) { + SDL20_memcpy(&audio_cbdata->cdrom_mp3, &mp3, sizeof (drmp3)); + } + } + SDL20_UnlockAudio(); + + return loaded ? 0 : SDL20_SetError("Failed to start CD track"); +} + + +DECLSPEC int SDLCALL +SDL_CDPlayTracks(SDL12_CD *cdrom, int start_track, int start_frame, int ntracks, int nframes) +{ + if ((cdrom = ValidCDDevice(cdrom)) == NULL) { + return -1; + } else if (cdrom->status == SDL12_CD_TRAYEMPTY) { + return SDL20_SetError("Tray empty"); + } else if ((start_track < 0) || (start_track >= cdrom->numtracks)) { + return SDL20_SetError("Invalid start track"); + } else if ((start_frame < 0) || (start_frame >= cdrom->track[start_track].length)) { + return SDL20_SetError("Invalid start frame"); + } else if ((ntracks < 0) || ((start_track + ntracks) >= cdrom->numtracks)) { + return SDL20_SetError("Invalid number of tracks"); + } else if ((nframes < 0) || (nframes >= cdrom->track[start_track + ntracks].length)) { + return SDL20_SetError("Invalid number of frames"); + } + + if (!ntracks && !nframes) { + ntracks = cdrom->numtracks - start_track; + nframes = cdrom->track[cdrom->numtracks - 1].length; + } + + return StartCDAudioPlaying(cdrom, start_track, start_frame, ntracks, nframes); +} + +DECLSPEC int SDLCALL +SDL_CDPlay(SDL12_CD *cdrom, int start, int length) +{ + int remain = length; + int start_track = -1; + int start_frame = -1; + int ntracks = -1; + int nframes = -1; + int i; + + if ((cdrom = ValidCDDevice(cdrom)) == NULL) { + return -1; + } else if (cdrom->status == SDL12_CD_TRAYEMPTY) { + return SDL20_SetError("Tray empty"); + } + + for (i = 0; i < cdrom->numtracks; i++) { + if ((start >= cdrom->track[i].offset) && (start < (cdrom->track[i].offset + cdrom->track[i].length))) { + start_track = i; + break; + } + } + + if (start_track == -1) { + return SDL20_SetError("Invalid start"); + } + + start_frame = start - cdrom->track[start_track].offset; + + if (remain < (cdrom->track[start_frame].length - start_frame)) { + ntracks = 0; + nframes = remain; + remain = 0; + } else { + remain -= (cdrom->track[start_frame].length - start_frame); + for (i = start_track + 1; i < cdrom->numtracks; i++) { + if (remain < cdrom->track[i].length) { + ntracks = i - start_track; + nframes = remain; + remain = 0; + break; + } + remain -= cdrom->track[i].length; + } + } + + if (remain) { + ntracks = (cdrom->numtracks - start_track) - 1; + nframes = cdrom->track[cdrom->numtracks - 1].length; + } + + return StartCDAudioPlaying(cdrom, start_track, start_frame, ntracks, nframes); +} + +DECLSPEC int SDLCALL +SDL_CDPause(SDL12_CD *cdrom) +{ + if ((cdrom = ValidCDDevice(cdrom)) == NULL) { + return -1; + } else if (cdrom->status == SDL12_CD_TRAYEMPTY) { + return SDL20_SetError("Tray empty"); + } + + SDL20_LockAudio(); + if (audio_cbdata) { + if (audio_cbdata->cdrom_status == SDL12_CD_PLAYING) { + audio_cbdata->cdrom_status = SDL12_CD_PAUSED; + } + cdrom->status = audio_cbdata->cdrom_status; + } + SDL20_UnlockAudio(); + return 0; +} + +DECLSPEC int SDLCALL +SDL_CDResume(SDL12_CD *cdrom) +{ + if ((cdrom = ValidCDDevice(cdrom)) == NULL) { + return -1; + } else if (cdrom->status == SDL12_CD_TRAYEMPTY) { + return SDL20_SetError("Tray empty"); + } + + SDL20_LockAudio(); + if (audio_cbdata) { + if (audio_cbdata->cdrom_status == SDL12_CD_PAUSED) { + audio_cbdata->cdrom_status = SDL12_CD_PLAYING; + } + cdrom->status = audio_cbdata->cdrom_status; + } + SDL20_UnlockAudio(); + return 0; +} + + +DECLSPEC int SDLCALL +SDL_CDStop(SDL12_CD *cdrom) +{ + SDL_RWops *oldrw = NULL; + + if ((cdrom = ValidCDDevice(cdrom)) == NULL) { + return -1; + } + + SDL20_LockAudio(); + if (audio_cbdata) { + if ((audio_cbdata->cdrom_status == SDL12_CD_PLAYING) || (audio_cbdata->cdrom_status == SDL12_CD_PAUSED)) { + audio_cbdata->cdrom_status = SDL12_CD_STOPPED; + FreeMp3(&audio_cbdata->cdrom_mp3); + } + cdrom->status = audio_cbdata->cdrom_status; + } + SDL20_UnlockAudio(); + + if (oldrw) { + SDL20_RWclose(oldrw); + } + return 0; +} + +DECLSPEC int SDLCALL +SDL_CDEject(SDL12_CD *cdrom) +{ + if ((cdrom = ValidCDDevice(cdrom)) == NULL) { + return -1; + } + + SDL20_LockAudio(); + if (audio_cbdata) { + audio_cbdata->cdrom_status = SDL12_CD_TRAYEMPTY; + FreeMp3(&audio_cbdata->cdrom_mp3); + } + cdrom->status = SDL12_CD_TRAYEMPTY; + SDL20_UnlockAudio(); + return 0; +} + +DECLSPEC void SDLCALL +SDL_CDClose(SDL12_CD *cdrom) +{ + if ((cdrom = ValidCDDevice(cdrom)) == NULL) { + return; + } + + SDL20_LockAudio(); + if (audio_cbdata) { + audio_cbdata->cdrom_opened = SDL_FALSE; + } + SDL20_UnlockAudio(); + + if (audio_cbdata) { + FreeMp3(&audio_cbdata->cdrom_mp3); + SDL20_FreeAudioStream(audio_cbdata->cdrom_stream); + audio_cbdata->cdrom_stream = NULL; + } + + CloseSDL2AudioDevice(); + + if (cdrom == CDRomDevice) { + CDRomDevice = NULL; + } + SDL20_free(cdrom); +} + + +static void +FakeCdRomAudioCallback(AudioCallbackWrapperData *data, Uint8 *stream, int len, const SDL_bool must_mix) +{ + Uint32 total_available, available = 0; + Uint32 channels, want_frames; + + if (data->cdrom_status != SDL12_CD_PLAYING) { + if (!must_mix) { + SDL20_memset(stream, data->device_format.silence, len); + } + return; + } + + SDL_assert((data->cdrom_status == SDL12_CD_PLAYING) && (data->cdrom_mp3.pUserData != NULL)); + + channels = data->cdrom_format.channels; + want_frames = data->cdrom_format.samples / channels; + + while ((!data->cdrom_mp3.atEnd) && (SDL20_AudioStreamAvailable(data->cdrom_stream) < len)) { + const Uint32 frames_read = (Uint32) drmp3_read_pcm_frames_f32(&data->cdrom_mp3, want_frames, (float *) data->mix_buffer); + const Uint32 bytes_read = frames_read * channels * sizeof (float); + SDL_assert(bytes_read <= data->cdrom_format.size); + if ((!bytes_read) || (SDL20_AudioStreamPut(data->cdrom_stream, data->mix_buffer, bytes_read) == -1)) { /* probably out of memory if failed */ + data->cdrom_mp3.atEnd = DRMP3_TRUE; /* force this to fail from now on */ + SDL20_AudioStreamFlush(data->cdrom_stream); /* make sure all we've put is available to get. */ + break; + } + } + + total_available = SDL20_AudioStreamAvailable(data->cdrom_stream); + available = (len < total_available) ? len : total_available; + if (len < available) { + available = len; + } + + if (available > 0) { + if (!must_mix) { + SDL20_AudioStreamGet(data->cdrom_stream, stream, available); + } else { + SDL20_AudioStreamGet(data->cdrom_stream, data->mix_buffer, available); + SDL20_MixAudio(stream, data->mix_buffer, available, SDL_MIX_MAXVOLUME); + } + + data->cdrom_pcm_frames_written += (available / ((double) SDL_AUDIO_BITSIZE(data->device_format.format) / 8.0)) / data->device_format.channels; + data->cdrom_cur_frame = (int) ((((double)data->cdrom_pcm_frames_written) / ((double)data->device_format.freq)) * CDAUDIO_FPS); + if (data->cdrom_stop_ntracks == 0) { + if (data->cdrom_cur_frame >= data->cdrom_stop_nframes) { + data->cdrom_mp3.atEnd = DRMP3_TRUE; /* played all that was requested! */ + } + } + } + + if ((total_available == 0) && (data->cdrom_mp3.atEnd)) { /* mp3 is done for whatever reason */ + SDL_bool silence = ((!must_mix) && (available < len)); /* silence any section we couldn't provide */ + + FreeMp3(&data->cdrom_mp3); + + if (data->cdrom_stop_ntracks > 0) { + data->cdrom_stop_ntracks--; + data->cdrom_pcm_frames_written = 0; + data->cdrom_cur_frame = 0; + + if (data->cdrom_status == SDL12_CD_PLAYING) { /* go on to next track? */ + const SDL_bool loaded = LoadCDTrack(++data->cdrom_cur_track, &data->cdrom_mp3); + if (!loaded) { + data->cdrom_status = SDL12_CD_TRAYEMPTY; FIXME("Maybe just mark it stopped?"); + } else { /* let new track fill out rest of callback. */ + if (available < len) { + FakeCdRomAudioCallback(data, stream + available, len - available, must_mix); + silence = SDL_FALSE; + } + } + } + } else { + data->cdrom_status = SDL12_CD_STOPPED; /* played all that was requested! */ + } + + if (silence) { + SDL20_memset(stream + available, data->device_format.silence, len - available); + } + } +} + + static void SDLCALL AudioCallbackWrapper(void *userdata, Uint8 *stream, int len) { AudioCallbackWrapperData *data = (AudioCallbackWrapperData *) userdata; - SDL20_memset(stream, data->silence, len); /* SDL2 doesn't clear the stream before calling in here, but 1.2 expects it. */ - data->app_callback(data->app_userdata, stream, len); + SDL_bool must_mix = SDL_FALSE; + + if (data->app_callback_opened && !data->app_callback_paused) { + while (SDL20_AudioStreamAvailable(data->app_callback_stream) < len) { + SDL20_memset(data->mix_buffer, data->app_callback_format.silence, data->app_callback_format.size); /* SDL2 doesn't clear the stream before calling in here, but 1.2 expects it. */ + data->app_callback_format.callback(data->app_callback_format.userdata, data->mix_buffer, data->app_callback_format.size); + if (SDL20_AudioStreamPut(data->app_callback_stream, data->mix_buffer, data->app_callback_format.size) == -1) { /* probably out of memory if failed */ + break; /* this will make the AudioStreamGet call fail. */ + } + } + if (SDL20_AudioStreamGet(data->app_callback_stream, stream, len) != len) { + SDL20_memset(stream, data->device_format.silence, len); + } else { + must_mix = SDL_TRUE; + } + } + + FakeCdRomAudioCallback(data, stream, len, must_mix); +} + + +static SDL_bool +ResetAudioStream(SDL_AudioStream **_stream, SDL_AudioSpec *spec, const SDL_AudioSpec *to, const SDL_AudioFormat fromfmt, const Uint8 fromchannels, const int fromfreq) +{ + if ((!*_stream) || (spec->channels != fromchannels) || (spec->format != fromfmt) || (spec->freq != fromfreq)) { + SDL20_FreeAudioStream(*_stream); + *_stream = SDL20_NewAudioStream(fromfmt, fromchannels, fromfreq, to->format, to->channels, to->freq); + if (!*_stream) { + return SDL_FALSE; + } + + spec->channels = fromchannels; + spec->format = fromfmt; + spec->freq = fromfreq; + spec->size = spec->samples * spec->channels * (SDL_AUDIO_BITSIZE(spec->format) / 8); + + if (audio_cbdata->mixbuflen < spec->size) { + void *ptr = SDL20_realloc(audio_cbdata->mix_buffer, spec->size); + if (!ptr) { + SDL20_FreeAudioStream(*_stream); + *_stream = NULL; + SDL20_OutOfMemory(); + return SDL_FALSE; + } + audio_cbdata->mixbuflen = spec->size; + audio_cbdata->mix_buffer = (Uint8 *) ptr; + } + } + return SDL_TRUE; +} + +static SDL_bool +ResetAudioStreamForDeviceChange(SDL_AudioStream **_stream, SDL_AudioSpec *spec) +{ + if (*_stream == NULL) { + return SDL_TRUE; /* no stream, no need to reset it. */ + } + SDL20_FreeAudioStream(*_stream); /* force it to rebuild because destination format changed. */ + *_stream = NULL; + return ResetAudioStream(_stream, spec, &audio_cbdata->device_format, spec->format, spec->channels, spec->freq); +} + +static int +OpenSDL2AudioDevice(SDL_AudioSpec *want) +{ + void (SDLCALL *orig_callback)(void *userdata, Uint8 *stream, int len) = want->callback; + void *orig_userdata = want->userdata; + int retval; + + /* Two things use the audio device: the app, through 1.2's SDL_OpenAudio, + and the fake CD-ROM device. Either can open the device, and both write + to SDL_AudioStreams to buffer and convert data. We try to open the device + in a format that accommodates both inputs, but we might close the device + and reopen it if we need more channels, etc. */ + if (audio_cbdata != NULL) { /* device is already open. */ + SDL_AudioSpec *have = &audio_cbdata->device_format; + if ( (want->freq > have->freq) || + (want->channels > have->channels) || + (want->samples > have->samples) || + ( (SDL_AUDIO_ISFLOAT(want->format)) && (!SDL_AUDIO_ISFLOAT(have->format)) ) || + ( SDL_AUDIO_BITSIZE(want->format) > SDL_AUDIO_BITSIZE(have->format) ) ) { + SDL20_CloseAudio(); + } else { + SDL20_LockAudio(); /* Device is already at acceptable parameters, just pause it for further setup by caller. */ + return SDL_TRUE; + } + } else { + audio_cbdata = (AudioCallbackWrapperData *) SDL20_calloc(1, sizeof (AudioCallbackWrapperData)); + if (!audio_cbdata) { + SDL20_OutOfMemory(); + return SDL_FALSE; + } + } + + FIXME("if this fails, we need to deal with app callback or cd-rom no longer working"); + want->callback = AudioCallbackWrapper; + want->userdata = audio_cbdata; + retval = (SDL20_OpenAudio(want, &audio_cbdata->device_format) == 0); + want->callback = orig_callback; + want->userdata = orig_userdata; + want->size = want->samples * want->channels * (SDL_AUDIO_BITSIZE(want->format) / 8); + + /* reset audiostreams if device format changed. */ + FIXME("deal with failure in here"); + ResetAudioStreamForDeviceChange(&audio_cbdata->app_callback_stream, &audio_cbdata->app_callback_format); + ResetAudioStreamForDeviceChange(&audio_cbdata->cdrom_stream, &audio_cbdata->cdrom_format); + + SDL20_LockAudio(); + SDL20_PauseAudio(0); /* always unpause, but caller will unlock after finalizing setup. */ + + return retval; +} + +static void +CloseSDL2AudioDevice(void) +{ + int close_sdl2_device; + + SDL20_LockAudio(); + close_sdl2_device = (audio_cbdata && !audio_cbdata->app_callback_opened && !audio_cbdata->cdrom_opened); + SDL20_UnlockAudio(); + + if (close_sdl2_device) { + SDL20_CloseAudio(); + SDL20_FreeAudioStream(audio_cbdata->app_callback_stream); + SDL20_FreeAudioStream(audio_cbdata->cdrom_stream); + SDL20_free(audio_cbdata->mix_buffer); + SDL20_free(audio_cbdata); + audio_cbdata = NULL; + } } DECLSPEC int SDLCALL SDL_OpenAudio(SDL_AudioSpec *want, SDL_AudioSpec *obtained) { - AudioCallbackWrapperData *data; - int retval; + int already_opened; /* SDL2 uses a NULL callback to mean "we plan to use SDL_QueueAudio()" */ if (want && (want->callback == NULL)) { return SDL20_SetError("Callback can't be NULL"); } - data = (AudioCallbackWrapperData *) SDL20_calloc(1, sizeof (AudioCallbackWrapperData)); - if (!data) { - return SDL20_OutOfMemory(); + SDL20_LockAudio(); + already_opened = audio_cbdata && audio_cbdata->app_callback_opened; + SDL20_UnlockAudio(); + if (already_opened) { + return SDL20_SetError("Audio device already opened"); } - data->app_callback = want->callback; - data->app_userdata = want->userdata; - want->callback = AudioCallbackWrapper; - want->userdata = data; - /* to avoid receiving a possible incompatible configuration - * from SDL2, always pass NULL as the 'obtained' pointer. */ + FIXME("Respect 1.2 environment variables for defining format here."); if (!want->format) { want->format = AUDIO_S16SYS; @@ -5749,29 +6506,73 @@ SDL_OpenAudio(SDL_AudioSpec *want, SDL_AudioSpec *obtained) while (pow2 < samp) pow2 <<= 1; want->samples = pow2; } - retval = SDL20_OpenAudio(want, NULL); - want->callback = data->app_callback; - want->userdata = data->app_userdata; - if (retval < 0) { - SDL20_free(data); - } else { - data->silence = want->silence; - SDL_assert(audio_cbdata==NULL); - audio_cbdata = data; - if (obtained) { - SDL20_memcpy(obtained, want, sizeof (SDL_AudioSpec)); - } + + /* the app always passes callback data through an SDL_AudioStream, since it + has to share with the fake CD-ROM support. This also avoids the risk of + getting an incompatible device configuration from SDL2. As such, + the app always gets the format it requests. */ + if (!OpenSDL2AudioDevice(want)) { + return -1; } + /* Device is locked now, unconditionally. Set up some things. */ + + if (obtained) { /* the app always gets the format it requests */ + SDL20_memcpy(obtained, want, sizeof (SDL_AudioSpec)); + } + + SDL20_memcpy(&audio_cbdata->app_callback_format, want, sizeof (SDL_AudioSpec)); + audio_cbdata->app_callback_opened = SDL_TRUE; + audio_cbdata->app_callback_paused = SDL_TRUE; /* app callback always starts paused after open. */ + + FIXME("Cleanup from failures in here"); + SDL_assert(audio_cbdata->app_callback_stream == NULL); + + if (!ResetAudioStream(&audio_cbdata->app_callback_stream, &audio_cbdata->app_callback_format, &audio_cbdata->device_format, want->format, want->channels, want->freq)) { + FIXME("Close audio device if nothing else was using it"); + return -1; + } + + SDL20_UnlockAudio(); /* we're off and going. */ + + return 0; +} + +DECLSPEC void SDLCALL +SDL_PauseAudio(int pause_on) +{ + SDL20_LockAudio(); + if (audio_cbdata && audio_cbdata->app_callback_opened) { + audio_cbdata->app_callback_paused = pause_on ? SDL_TRUE : SDL_FALSE; + } + SDL20_UnlockAudio(); +} + +DECLSPEC SDL_AudioStatus SDLCALL +SDL_GetAudioStatus(void) +{ + SDL_AudioStatus retval = SDL_AUDIO_STOPPED; + SDL20_LockAudio(); + if (audio_cbdata && audio_cbdata->app_callback_opened) { + retval = audio_cbdata->app_callback_paused ? SDL_AUDIO_PAUSED : SDL_AUDIO_PLAYING; + } + SDL20_UnlockAudio(); return retval; } DECLSPEC void SDLCALL SDL_CloseAudio(void) { - SDL20_CloseAudio(); - SDL20_free(audio_cbdata); - audio_cbdata = NULL; + SDL20_LockAudio(); + if (audio_cbdata) { + audio_cbdata->app_callback_opened = SDL_FALSE; + } + SDL20_UnlockAudio(); + + SDL20_FreeAudioStream(audio_cbdata->app_callback_stream); + audio_cbdata->app_callback_stream = NULL; + + CloseSDL2AudioDevice(); } diff --git a/src/SDL20_syms.h b/src/SDL20_syms.h index 29b1007e9..9a8ef5b31 100644 --- a/src/SDL20_syms.h +++ b/src/SDL20_syms.h @@ -191,8 +191,8 @@ SDL20_SYM_PASSTHROUGH(int,CondWaitTimeout,(SDL_cond *a, SDL_mutex *b, Uint32 c), SDL20_SYM(SDL_AudioSpec *,LoadWAV_RW,(SDL_RWops *a, int b, SDL_AudioSpec *c, Uint8 **d, Uint32 *e),(a,b,c,d,e),return) SDL20_SYM(int,OpenAudio,(SDL_AudioSpec *a, SDL_AudioSpec *b),(a,b),return) SDL20_SYM(void,CloseAudio,(void),(),) -SDL20_SYM_PASSTHROUGH(SDL_AudioStatus,GetAudioStatus,(void),(),return) -SDL20_SYM_PASSTHROUGH(void,PauseAudio,(int a),(a),) +SDL20_SYM(SDL_AudioStatus,GetAudioStatus,(void),(),return) +SDL20_SYM(void,PauseAudio,(int a),(a),) SDL20_SYM_PASSTHROUGH(void,FreeWAV,(Uint8 *a),(a),) SDL20_SYM_PASSTHROUGH(int,BuildAudioCVT,(SDL_AudioCVT *a, Uint16 b, Uint8 c, int d, Uint16 e, Uint8 f, int g),(a,b,c,d,e,f,g),return) SDL20_SYM_PASSTHROUGH(int,ConvertAudio,(SDL_AudioCVT *a),(a),return) @@ -200,6 +200,14 @@ SDL20_SYM_PASSTHROUGH(void,MixAudio,(Uint8 *a, const Uint8 *b, Uint32 c, int d), SDL20_SYM_PASSTHROUGH(void,LockAudio,(void),(),) SDL20_SYM_PASSTHROUGH(void,UnlockAudio,(void),(),) +SDL20_SYM(SDL_AudioStream *,NewAudioStream,(const SDL_AudioFormat a, const Uint8 b, const int c, const SDL_AudioFormat d, const Uint8 e, const int f),(a,b,c,d,e,f),return) +SDL20_SYM(int,AudioStreamPut,(SDL_AudioStream *a, const void *b, int c),(a,b,c),return) +SDL20_SYM(int,AudioStreamGet,(SDL_AudioStream *a, void *b, int c),(a,b,c),return) +SDL20_SYM(int,AudioStreamAvailable,(SDL_AudioStream *a),(a),return) +SDL20_SYM(int,AudioStreamFlush,(SDL_AudioStream *a),(a),return) +SDL20_SYM(void,AudioStreamClear,(SDL_AudioStream *a),(a),) +SDL20_SYM(void,FreeAudioStream,(SDL_AudioStream *a),(a),) + SDL20_SYM_PASSTHROUGH(void*,LoadObject,(const char *a),(a),return) SDL20_SYM_PASSTHROUGH(void*,LoadFunction,(void *a, const char *b),(a,b),return) SDL20_SYM_PASSTHROUGH(void,UnloadObject,(void *a),(a),) @@ -239,6 +247,12 @@ SDL20_SYM(SDL_RWops *,RWFromMem,(void *a, int b),(a,b),return) SDL20_SYM(SDL_RWops *,RWFromConstMem,(const void *a, int b),(a,b),return) SDL20_SYM(SDL_RWops *,AllocRW,(void),(),return) SDL20_SYM(void,FreeRW,(SDL_RWops *a),(a),) +SDL20_SYM(Sint64,RWsize,(SDL_RWops *a),(a),return) +SDL20_SYM(Sint64,RWseek,(SDL_RWops *a, Sint64 b, int c),(a,b,c),return) +SDL20_SYM(Sint64,RWtell,(SDL_RWops *a),(a),return) +SDL20_SYM(size_t,RWread,(SDL_RWops *a, void *b, size_t c, size_t d),(a,b,c,d),return) +SDL20_SYM(size_t,RWwrite,(SDL_RWops *a, const void *b, size_t c, size_t d),(a,b,c,d),return) +SDL20_SYM(int,RWclose,(SDL_RWops *a),(a),return) SDL20_SYM_PASSTHROUGH(void *,malloc,(size_t a),(a),return) SDL20_SYM_PASSTHROUGH(void *,calloc,(size_t a, size_t b),(a,b),return) @@ -248,6 +262,8 @@ SDL20_SYM_PASSTHROUGH(char *,getenv,(const char *a),(a),return) SDL20_SYM_PASSTHROUGH(void,qsort,(void *a, size_t b, size_t c, int (*d)(const void *, const void *)),(a,b,c,d),) SDL20_SYM_PASSTHROUGH(void *,memset,(void *a, int b, size_t c),(a,b,c),return) SDL20_SYM_PASSTHROUGH(void *,memcpy,(void *a, const void *b, size_t c),(a,b,c),return) +SDL20_SYM(void *,memmove,(void *a, const void *b, size_t c),(a,b,c),return) + SDL20_SYM_PASSTHROUGH(int,memcmp,(const void *a, const void *b, size_t c),(a,b,c),return) SDL20_SYM_PASSTHROUGH(size_t,strlen,(const char *a),(a),return) SDL20_SYM_PASSTHROUGH(size_t,strlcpy,(char *a, const char *b, size_t c),(a,b,c),return) diff --git a/src/dr_mp3.h b/src/dr_mp3.h new file mode 100644 index 000000000..e28f318bc --- /dev/null +++ b/src/dr_mp3.h @@ -0,0 +1,4750 @@ +/* +MP3 audio decoder. Choice of public domain or MIT-0. See license statements at the end of this file. +dr_mp3 - v0.6.27 - 2021-02-21 + +David Reid - mackron@gmail.com + +GitHub: https://github.com/mackron/dr_libs + +Based on minimp3 (https://github.com/lieff/minimp3) which is where the real work was done. See the bottom of this file for differences between minimp3 and dr_mp3. +*/ + +/* +RELEASE NOTES - VERSION 0.6 +=========================== +Version 0.6 includes breaking changes with the configuration of decoders. The ability to customize the number of output channels and the sample rate has been +removed. You must now use the channel count and sample rate reported by the MP3 stream itself, and all channel and sample rate conversion must be done +yourself. + + +Changes to Initialization +------------------------- +Previously, `drmp3_init()`, etc. took a pointer to a `drmp3_config` object that allowed you to customize the output channels and sample rate. This has been +removed. If you need the old behaviour you will need to convert the data yourself or just not upgrade. The following APIs have changed. + + `drmp3_init()` + `drmp3_init_memory()` + `drmp3_init_file()` + + +Miscellaneous Changes +--------------------- +Support for loading a file from a `wchar_t` string has been added via the `drmp3_init_file_w()` API. +*/ + +/* +Introducation +============= +dr_mp3 is a single file library. To use it, do something like the following in one .c file. + + ```c + #define DR_MP3_IMPLEMENTATION + #include "dr_mp3.h" + ``` + +You can then #include this file in other parts of the program as you would with any other header file. To decode audio data, do something like the following: + + ```c + drmp3 mp3; + if (!drmp3_init_file(&mp3, "MySong.mp3", NULL)) { + // Failed to open file + } + + ... + + drmp3_uint64 framesRead = drmp3_read_pcm_frames_f32(pMP3, framesToRead, pFrames); + ``` + +The drmp3 object is transparent so you can get access to the channel count and sample rate like so: + + ``` + drmp3_uint32 channels = mp3.channels; + drmp3_uint32 sampleRate = mp3.sampleRate; + ``` + +The example above initializes a decoder from a file, but you can also initialize it from a block of memory and read and seek callbacks with +`drmp3_init_memory()` and `drmp3_init()` respectively. + +You do not need to do any annoying memory management when reading PCM frames - this is all managed internally. You can request any number of PCM frames in each +call to `drmp3_read_pcm_frames_f32()` and it will return as many PCM frames as it can, up to the requested amount. + +You can also decode an entire file in one go with `drmp3_open_and_read_pcm_frames_f32()`, `drmp3_open_memory_and_read_pcm_frames_f32()` and +`drmp3_open_file_and_read_pcm_frames_f32()`. + + +Build Options +============= +#define these options before including this file. + +#define DR_MP3_NO_STDIO + Disable drmp3_init_file(), etc. + +#define DR_MP3_NO_SIMD + Disable SIMD optimizations. +*/ + +#ifndef dr_mp3_h +#define dr_mp3_h + +#ifdef __cplusplus +extern "C" { +#endif + +#define DRMP3_STRINGIFY(x) #x +#define DRMP3_XSTRINGIFY(x) DRMP3_STRINGIFY(x) + +#define DRMP3_VERSION_MAJOR 0 +#define DRMP3_VERSION_MINOR 6 +#define DRMP3_VERSION_REVISION 27 +#define DRMP3_VERSION_STRING DRMP3_XSTRINGIFY(DRMP3_VERSION_MAJOR) "." DRMP3_XSTRINGIFY(DRMP3_VERSION_MINOR) "." DRMP3_XSTRINGIFY(DRMP3_VERSION_REVISION) + +#include /* For size_t. */ + +/* Sized types. */ +typedef signed char drmp3_int8; +typedef unsigned char drmp3_uint8; +typedef signed short drmp3_int16; +typedef unsigned short drmp3_uint16; +typedef signed int drmp3_int32; +typedef unsigned int drmp3_uint32; +#if defined(_MSC_VER) + typedef signed __int64 drmp3_int64; + typedef unsigned __int64 drmp3_uint64; +#else + #if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wlong-long" + #if defined(__clang__) + #pragma GCC diagnostic ignored "-Wc++11-long-long" + #endif + #endif + typedef signed long long drmp3_int64; + typedef unsigned long long drmp3_uint64; + #if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))) + #pragma GCC diagnostic pop + #endif +#endif +#if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__)) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__) + typedef drmp3_uint64 drmp3_uintptr; +#else + typedef drmp3_uint32 drmp3_uintptr; +#endif +typedef drmp3_uint8 drmp3_bool8; +typedef drmp3_uint32 drmp3_bool32; +#define DRMP3_TRUE 1 +#define DRMP3_FALSE 0 + +#if !defined(DRMP3_API) + #if defined(DRMP3_DLL) + #if defined(_WIN32) + #define DRMP3_DLL_IMPORT __declspec(dllimport) + #define DRMP3_DLL_EXPORT __declspec(dllexport) + #define DRMP3_DLL_PRIVATE static + #else + #if defined(__GNUC__) && __GNUC__ >= 4 + #define DRMP3_DLL_IMPORT __attribute__((visibility("default"))) + #define DRMP3_DLL_EXPORT __attribute__((visibility("default"))) + #define DRMP3_DLL_PRIVATE __attribute__((visibility("hidden"))) + #else + #define DRMP3_DLL_IMPORT + #define DRMP3_DLL_EXPORT + #define DRMP3_DLL_PRIVATE static + #endif + #endif + + #if defined(DR_MP3_IMPLEMENTATION) || defined(DRMP3_IMPLEMENTATION) + #define DRMP3_API DRMP3_DLL_EXPORT + #else + #define DRMP3_API DRMP3_DLL_IMPORT + #endif + #define DRMP3_PRIVATE DRMP3_DLL_PRIVATE + #else + #define DRMP3_API extern + #define DRMP3_PRIVATE static + #endif +#endif + +typedef drmp3_int32 drmp3_result; +#define DRMP3_SUCCESS 0 +#define DRMP3_ERROR -1 /* A generic error. */ +#define DRMP3_INVALID_ARGS -2 +#define DRMP3_INVALID_OPERATION -3 +#define DRMP3_OUT_OF_MEMORY -4 +#define DRMP3_OUT_OF_RANGE -5 +#define DRMP3_ACCESS_DENIED -6 +#define DRMP3_DOES_NOT_EXIST -7 +#define DRMP3_ALREADY_EXISTS -8 +#define DRMP3_TOO_MANY_OPEN_FILES -9 +#define DRMP3_INVALID_FILE -10 +#define DRMP3_TOO_BIG -11 +#define DRMP3_PATH_TOO_LONG -12 +#define DRMP3_NAME_TOO_LONG -13 +#define DRMP3_NOT_DIRECTORY -14 +#define DRMP3_IS_DIRECTORY -15 +#define DRMP3_DIRECTORY_NOT_EMPTY -16 +#define DRMP3_END_OF_FILE -17 +#define DRMP3_NO_SPACE -18 +#define DRMP3_BUSY -19 +#define DRMP3_IO_ERROR -20 +#define DRMP3_INTERRUPT -21 +#define DRMP3_UNAVAILABLE -22 +#define DRMP3_ALREADY_IN_USE -23 +#define DRMP3_BAD_ADDRESS -24 +#define DRMP3_BAD_SEEK -25 +#define DRMP3_BAD_PIPE -26 +#define DRMP3_DEADLOCK -27 +#define DRMP3_TOO_MANY_LINKS -28 +#define DRMP3_NOT_IMPLEMENTED -29 +#define DRMP3_NO_MESSAGE -30 +#define DRMP3_BAD_MESSAGE -31 +#define DRMP3_NO_DATA_AVAILABLE -32 +#define DRMP3_INVALID_DATA -33 +#define DRMP3_TIMEOUT -34 +#define DRMP3_NO_NETWORK -35 +#define DRMP3_NOT_UNIQUE -36 +#define DRMP3_NOT_SOCKET -37 +#define DRMP3_NO_ADDRESS -38 +#define DRMP3_BAD_PROTOCOL -39 +#define DRMP3_PROTOCOL_UNAVAILABLE -40 +#define DRMP3_PROTOCOL_NOT_SUPPORTED -41 +#define DRMP3_PROTOCOL_FAMILY_NOT_SUPPORTED -42 +#define DRMP3_ADDRESS_FAMILY_NOT_SUPPORTED -43 +#define DRMP3_SOCKET_NOT_SUPPORTED -44 +#define DRMP3_CONNECTION_RESET -45 +#define DRMP3_ALREADY_CONNECTED -46 +#define DRMP3_NOT_CONNECTED -47 +#define DRMP3_CONNECTION_REFUSED -48 +#define DRMP3_NO_HOST -49 +#define DRMP3_IN_PROGRESS -50 +#define DRMP3_CANCELLED -51 +#define DRMP3_MEMORY_ALREADY_MAPPED -52 +#define DRMP3_AT_END -53 + + +#define DRMP3_MAX_PCM_FRAMES_PER_MP3_FRAME 1152 +#define DRMP3_MAX_SAMPLES_PER_FRAME (DRMP3_MAX_PCM_FRAMES_PER_MP3_FRAME*2) + +#ifdef _MSC_VER + #define DRMP3_INLINE __forceinline +#elif defined(__GNUC__) + /* + I've had a bug report where GCC is emitting warnings about functions possibly not being inlineable. This warning happens when + the __attribute__((always_inline)) attribute is defined without an "inline" statement. I think therefore there must be some + case where "__inline__" is not always defined, thus the compiler emitting these warnings. When using -std=c89 or -ansi on the + command line, we cannot use the "inline" keyword and instead need to use "__inline__". In an attempt to work around this issue + I am using "__inline__" only when we're compiling in strict ANSI mode. + */ + #if defined(__STRICT_ANSI__) + #define DRMP3_INLINE __inline__ __attribute__((always_inline)) + #else + #define DRMP3_INLINE inline __attribute__((always_inline)) + #endif +#elif defined(__WATCOMC__) + #define DRMP3_INLINE __inline +#else + #define DRMP3_INLINE +#endif + + +DRMP3_API void drmp3_version(drmp3_uint32* pMajor, drmp3_uint32* pMinor, drmp3_uint32* pRevision); +DRMP3_API const char* drmp3_version_string(void); + + +/* +Low Level Push API +================== +*/ +typedef struct +{ + int frame_bytes, channels, hz, layer, bitrate_kbps; +} drmp3dec_frame_info; + +typedef struct +{ + float mdct_overlap[2][9*32], qmf_state[15*2*32]; + int reserv, free_format_bytes; + drmp3_uint8 header[4], reserv_buf[511]; +} drmp3dec; + +/* Initializes a low level decoder. */ +DRMP3_API void drmp3dec_init(drmp3dec *dec); + +/* Reads a frame from a low level decoder. */ +DRMP3_API int drmp3dec_decode_frame(drmp3dec *dec, const drmp3_uint8 *mp3, int mp3_bytes, void *pcm, drmp3dec_frame_info *info); + +/* Helper for converting between f32 and s16. */ +DRMP3_API void drmp3dec_f32_to_s16(const float *in, drmp3_int16 *out, size_t num_samples); + + + +/* +Main API (Pull API) +=================== +*/ +typedef enum +{ + drmp3_seek_origin_start, + drmp3_seek_origin_current +} drmp3_seek_origin; + +typedef struct +{ + drmp3_uint64 seekPosInBytes; /* Points to the first byte of an MP3 frame. */ + drmp3_uint64 pcmFrameIndex; /* The index of the PCM frame this seek point targets. */ + drmp3_uint16 mp3FramesToDiscard; /* The number of whole MP3 frames to be discarded before pcmFramesToDiscard. */ + drmp3_uint16 pcmFramesToDiscard; /* The number of leading samples to read and discard. These are discarded after mp3FramesToDiscard. */ +} drmp3_seek_point; + +/* +Callback for when data is read. Return value is the number of bytes actually read. + +pUserData [in] The user data that was passed to drmp3_init(), drmp3_open() and family. +pBufferOut [out] The output buffer. +bytesToRead [in] The number of bytes to read. + +Returns the number of bytes actually read. + +A return value of less than bytesToRead indicates the end of the stream. Do _not_ return from this callback until +either the entire bytesToRead is filled or you have reached the end of the stream. +*/ +typedef size_t (* drmp3_read_proc)(void* pUserData, void* pBufferOut, size_t bytesToRead); + +/* +Callback for when data needs to be seeked. + +pUserData [in] The user data that was passed to drmp3_init(), drmp3_open() and family. +offset [in] The number of bytes to move, relative to the origin. Will never be negative. +origin [in] The origin of the seek - the current position or the start of the stream. + +Returns whether or not the seek was successful. + +Whether or not it is relative to the beginning or current position is determined by the "origin" parameter which +will be either drmp3_seek_origin_start or drmp3_seek_origin_current. +*/ +typedef drmp3_bool32 (* drmp3_seek_proc)(void* pUserData, int offset, drmp3_seek_origin origin); + +typedef struct +{ + void* pUserData; + void* (* onMalloc)(size_t sz, void* pUserData); + void* (* onRealloc)(void* p, size_t sz, void* pUserData); + void (* onFree)(void* p, void* pUserData); +} drmp3_allocation_callbacks; + +typedef struct +{ + drmp3_uint32 channels; + drmp3_uint32 sampleRate; +} drmp3_config; + +typedef struct +{ + drmp3dec decoder; + drmp3dec_frame_info frameInfo; + drmp3_uint32 channels; + drmp3_uint32 sampleRate; + drmp3_read_proc onRead; + drmp3_seek_proc onSeek; + void* pUserData; + drmp3_allocation_callbacks allocationCallbacks; + drmp3_uint32 mp3FrameChannels; /* The number of channels in the currently loaded MP3 frame. Internal use only. */ + drmp3_uint32 mp3FrameSampleRate; /* The sample rate of the currently loaded MP3 frame. Internal use only. */ + drmp3_uint32 pcmFramesConsumedInMP3Frame; + drmp3_uint32 pcmFramesRemainingInMP3Frame; + drmp3_uint8 pcmFrames[sizeof(float)*DRMP3_MAX_SAMPLES_PER_FRAME]; /* <-- Multipled by sizeof(float) to ensure there's enough room for DR_MP3_FLOAT_OUTPUT. */ + drmp3_uint64 currentPCMFrame; /* The current PCM frame, globally, based on the output sample rate. Mainly used for seeking. */ + drmp3_uint64 streamCursor; /* The current byte the decoder is sitting on in the raw stream. */ + drmp3_seek_point* pSeekPoints; /* NULL by default. Set with drmp3_bind_seek_table(). Memory is owned by the client. dr_mp3 will never attempt to free this pointer. */ + drmp3_uint32 seekPointCount; /* The number of items in pSeekPoints. When set to 0 assumes to no seek table. Defaults to zero. */ + size_t dataSize; + size_t dataCapacity; + size_t dataConsumed; + drmp3_uint8* pData; + drmp3_bool32 atEnd : 1; + struct + { + const drmp3_uint8* pData; + size_t dataSize; + size_t currentReadPos; + } memory; /* Only used for decoders that were opened against a block of memory. */ +} drmp3; + +/* +Initializes an MP3 decoder. + +onRead [in] The function to call when data needs to be read from the client. +onSeek [in] The function to call when the read position of the client data needs to move. +pUserData [in, optional] A pointer to application defined data that will be passed to onRead and onSeek. + +Returns true if successful; false otherwise. + +Close the loader with drmp3_uninit(). + +See also: drmp3_init_file(), drmp3_init_memory(), drmp3_uninit() +*/ +DRMP3_API drmp3_bool32 drmp3_init(drmp3* pMP3, drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, const drmp3_allocation_callbacks* pAllocationCallbacks); + +/* +Initializes an MP3 decoder from a block of memory. + +This does not create a copy of the data. It is up to the application to ensure the buffer remains valid for +the lifetime of the drmp3 object. + +The buffer should contain the contents of the entire MP3 file. +*/ +DRMP3_API drmp3_bool32 drmp3_init_memory(drmp3* pMP3, const void* pData, size_t dataSize, const drmp3_allocation_callbacks* pAllocationCallbacks); + +#ifndef DR_MP3_NO_STDIO +/* +Initializes an MP3 decoder from a file. + +This holds the internal FILE object until drmp3_uninit() is called. Keep this in mind if you're caching drmp3 +objects because the operating system may restrict the number of file handles an application can have open at +any given time. +*/ +DRMP3_API drmp3_bool32 drmp3_init_file(drmp3* pMP3, const char* pFilePath, const drmp3_allocation_callbacks* pAllocationCallbacks); +DRMP3_API drmp3_bool32 drmp3_init_file_w(drmp3* pMP3, const wchar_t* pFilePath, const drmp3_allocation_callbacks* pAllocationCallbacks); +#endif + +/* +Uninitializes an MP3 decoder. +*/ +DRMP3_API void drmp3_uninit(drmp3* pMP3); + +/* +Reads PCM frames as interleaved 32-bit IEEE floating point PCM. + +Note that framesToRead specifies the number of PCM frames to read, _not_ the number of MP3 frames. +*/ +DRMP3_API drmp3_uint64 drmp3_read_pcm_frames_f32(drmp3* pMP3, drmp3_uint64 framesToRead, float* pBufferOut); + +/* +Reads PCM frames as interleaved signed 16-bit integer PCM. + +Note that framesToRead specifies the number of PCM frames to read, _not_ the number of MP3 frames. +*/ +DRMP3_API drmp3_uint64 drmp3_read_pcm_frames_s16(drmp3* pMP3, drmp3_uint64 framesToRead, drmp3_int16* pBufferOut); + +/* +Seeks to a specific frame. + +Note that this is _not_ an MP3 frame, but rather a PCM frame. +*/ +DRMP3_API drmp3_bool32 drmp3_seek_to_pcm_frame(drmp3* pMP3, drmp3_uint64 frameIndex); + +/* +Calculates the total number of PCM frames in the MP3 stream. Cannot be used for infinite streams such as internet +radio. Runs in linear time. Returns 0 on error. +*/ +DRMP3_API drmp3_uint64 drmp3_get_pcm_frame_count(drmp3* pMP3); + +/* +Calculates the total number of MP3 frames in the MP3 stream. Cannot be used for infinite streams such as internet +radio. Runs in linear time. Returns 0 on error. +*/ +DRMP3_API drmp3_uint64 drmp3_get_mp3_frame_count(drmp3* pMP3); + +/* +Calculates the total number of MP3 and PCM frames in the MP3 stream. Cannot be used for infinite streams such as internet +radio. Runs in linear time. Returns 0 on error. + +This is equivalent to calling drmp3_get_mp3_frame_count() and drmp3_get_pcm_frame_count() except that it's more efficient. +*/ +DRMP3_API drmp3_bool32 drmp3_get_mp3_and_pcm_frame_count(drmp3* pMP3, drmp3_uint64* pMP3FrameCount, drmp3_uint64* pPCMFrameCount); + +/* +Calculates the seekpoints based on PCM frames. This is slow. + +pSeekpoint count is a pointer to a uint32 containing the seekpoint count. On input it contains the desired count. +On output it contains the actual count. The reason for this design is that the client may request too many +seekpoints, in which case dr_mp3 will return a corrected count. + +Note that seektable seeking is not quite sample exact when the MP3 stream contains inconsistent sample rates. +*/ +DRMP3_API drmp3_bool32 drmp3_calculate_seek_points(drmp3* pMP3, drmp3_uint32* pSeekPointCount, drmp3_seek_point* pSeekPoints); + +/* +Binds a seek table to the decoder. + +This does _not_ make a copy of pSeekPoints - it only references it. It is up to the application to ensure this +remains valid while it is bound to the decoder. + +Use drmp3_calculate_seek_points() to calculate the seek points. +*/ +DRMP3_API drmp3_bool32 drmp3_bind_seek_table(drmp3* pMP3, drmp3_uint32 seekPointCount, drmp3_seek_point* pSeekPoints); + + +/* +Opens an decodes an entire MP3 stream as a single operation. + +On output pConfig will receive the channel count and sample rate of the stream. + +Free the returned pointer with drmp3_free(). +*/ +DRMP3_API float* drmp3_open_and_read_pcm_frames_f32(drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks); +DRMP3_API drmp3_int16* drmp3_open_and_read_pcm_frames_s16(drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks); + +DRMP3_API float* drmp3_open_memory_and_read_pcm_frames_f32(const void* pData, size_t dataSize, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks); +DRMP3_API drmp3_int16* drmp3_open_memory_and_read_pcm_frames_s16(const void* pData, size_t dataSize, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks); + +#ifndef DR_MP3_NO_STDIO +DRMP3_API float* drmp3_open_file_and_read_pcm_frames_f32(const char* filePath, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks); +DRMP3_API drmp3_int16* drmp3_open_file_and_read_pcm_frames_s16(const char* filePath, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks); +#endif + +/* +Allocates a block of memory on the heap. +*/ +DRMP3_API void* drmp3_malloc(size_t sz, const drmp3_allocation_callbacks* pAllocationCallbacks); + +/* +Frees any memory that was allocated by a public drmp3 API. +*/ +DRMP3_API void drmp3_free(void* p, const drmp3_allocation_callbacks* pAllocationCallbacks); + +#ifdef __cplusplus +} +#endif +#endif /* dr_mp3_h */ + + +/************************************************************************************************************************************************************ + ************************************************************************************************************************************************************ + + IMPLEMENTATION + + ************************************************************************************************************************************************************ + ************************************************************************************************************************************************************/ +#if defined(DR_MP3_IMPLEMENTATION) || defined(DRMP3_IMPLEMENTATION) +#ifndef dr_mp3_c +#define dr_mp3_c + +#include +#include +#include /* For INT_MAX */ + +DRMP3_API void drmp3_version(drmp3_uint32* pMajor, drmp3_uint32* pMinor, drmp3_uint32* pRevision) +{ + if (pMajor) { + *pMajor = DRMP3_VERSION_MAJOR; + } + + if (pMinor) { + *pMinor = DRMP3_VERSION_MINOR; + } + + if (pRevision) { + *pRevision = DRMP3_VERSION_REVISION; + } +} + +DRMP3_API const char* drmp3_version_string(void) +{ + return DRMP3_VERSION_STRING; +} + +/* Disable SIMD when compiling with TCC for now. */ +#if defined(__TINYC__) +#define DR_MP3_NO_SIMD +#endif + +#define DRMP3_OFFSET_PTR(p, offset) ((void*)((drmp3_uint8*)(p) + (offset))) + +#define DRMP3_MAX_FREE_FORMAT_FRAME_SIZE 2304 /* more than ISO spec's */ +#ifndef DRMP3_MAX_FRAME_SYNC_MATCHES +#define DRMP3_MAX_FRAME_SYNC_MATCHES 10 +#endif + +#define DRMP3_MAX_L3_FRAME_PAYLOAD_BYTES DRMP3_MAX_FREE_FORMAT_FRAME_SIZE /* MUST be >= 320000/8/32000*1152 = 1440 */ + +#define DRMP3_MAX_BITRESERVOIR_BYTES 511 +#define DRMP3_SHORT_BLOCK_TYPE 2 +#define DRMP3_STOP_BLOCK_TYPE 3 +#define DRMP3_MODE_MONO 3 +#define DRMP3_MODE_JOINT_STEREO 1 +#define DRMP3_HDR_SIZE 4 +#define DRMP3_HDR_IS_MONO(h) (((h[3]) & 0xC0) == 0xC0) +#define DRMP3_HDR_IS_MS_STEREO(h) (((h[3]) & 0xE0) == 0x60) +#define DRMP3_HDR_IS_FREE_FORMAT(h) (((h[2]) & 0xF0) == 0) +#define DRMP3_HDR_IS_CRC(h) (!((h[1]) & 1)) +#define DRMP3_HDR_TEST_PADDING(h) ((h[2]) & 0x2) +#define DRMP3_HDR_TEST_MPEG1(h) ((h[1]) & 0x8) +#define DRMP3_HDR_TEST_NOT_MPEG25(h) ((h[1]) & 0x10) +#define DRMP3_HDR_TEST_I_STEREO(h) ((h[3]) & 0x10) +#define DRMP3_HDR_TEST_MS_STEREO(h) ((h[3]) & 0x20) +#define DRMP3_HDR_GET_STEREO_MODE(h) (((h[3]) >> 6) & 3) +#define DRMP3_HDR_GET_STEREO_MODE_EXT(h) (((h[3]) >> 4) & 3) +#define DRMP3_HDR_GET_LAYER(h) (((h[1]) >> 1) & 3) +#define DRMP3_HDR_GET_BITRATE(h) ((h[2]) >> 4) +#define DRMP3_HDR_GET_SAMPLE_RATE(h) (((h[2]) >> 2) & 3) +#define DRMP3_HDR_GET_MY_SAMPLE_RATE(h) (DRMP3_HDR_GET_SAMPLE_RATE(h) + (((h[1] >> 3) & 1) + ((h[1] >> 4) & 1))*3) +#define DRMP3_HDR_IS_FRAME_576(h) ((h[1] & 14) == 2) +#define DRMP3_HDR_IS_LAYER_1(h) ((h[1] & 6) == 6) + +#define DRMP3_BITS_DEQUANTIZER_OUT -1 +#define DRMP3_MAX_SCF (255 + DRMP3_BITS_DEQUANTIZER_OUT*4 - 210) +#define DRMP3_MAX_SCFI ((DRMP3_MAX_SCF + 3) & ~3) + +#define DRMP3_MIN(a, b) ((a) > (b) ? (b) : (a)) +#define DRMP3_MAX(a, b) ((a) < (b) ? (b) : (a)) + +#if !defined(DR_MP3_NO_SIMD) + +#if !defined(DR_MP3_ONLY_SIMD) && (defined(_M_X64) || defined(__x86_64__) || defined(__aarch64__) || defined(_M_ARM64)) +/* x64 always have SSE2, arm64 always have neon, no need for generic code */ +#define DR_MP3_ONLY_SIMD +#endif + +#if ((defined(_MSC_VER) && _MSC_VER >= 1400) && (defined(_M_IX86) || defined(_M_X64))) || ((defined(__i386__) || defined(__x86_64__)) && defined(__SSE2__)) +#if defined(_MSC_VER) +#include +#endif +#include +#define DRMP3_HAVE_SSE 1 +#define DRMP3_HAVE_SIMD 1 +#define DRMP3_VSTORE _mm_storeu_ps +#define DRMP3_VLD _mm_loadu_ps +#define DRMP3_VSET _mm_set1_ps +#define DRMP3_VADD _mm_add_ps +#define DRMP3_VSUB _mm_sub_ps +#define DRMP3_VMUL _mm_mul_ps +#define DRMP3_VMAC(a, x, y) _mm_add_ps(a, _mm_mul_ps(x, y)) +#define DRMP3_VMSB(a, x, y) _mm_sub_ps(a, _mm_mul_ps(x, y)) +#define DRMP3_VMUL_S(x, s) _mm_mul_ps(x, _mm_set1_ps(s)) +#define DRMP3_VREV(x) _mm_shuffle_ps(x, x, _MM_SHUFFLE(0, 1, 2, 3)) +typedef __m128 drmp3_f4; +#if defined(_MSC_VER) || defined(DR_MP3_ONLY_SIMD) +#define drmp3_cpuid __cpuid +#else +static __inline__ __attribute__((always_inline)) void drmp3_cpuid(int CPUInfo[], const int InfoType) +{ +#if defined(__PIC__) + __asm__ __volatile__( +#if defined(__x86_64__) + "push %%rbx\n" + "cpuid\n" + "xchgl %%ebx, %1\n" + "pop %%rbx\n" +#else + "xchgl %%ebx, %1\n" + "cpuid\n" + "xchgl %%ebx, %1\n" +#endif + : "=a" (CPUInfo[0]), "=r" (CPUInfo[1]), "=c" (CPUInfo[2]), "=d" (CPUInfo[3]) + : "a" (InfoType)); +#else + __asm__ __volatile__( + "cpuid" + : "=a" (CPUInfo[0]), "=b" (CPUInfo[1]), "=c" (CPUInfo[2]), "=d" (CPUInfo[3]) + : "a" (InfoType)); +#endif +} +#endif +static int drmp3_have_simd(void) +{ +#ifdef DR_MP3_ONLY_SIMD + return 1; +#else + static int g_have_simd; + int CPUInfo[4]; +#ifdef MINIMP3_TEST + static int g_counter; + if (g_counter++ > 100) + return 0; +#endif + if (g_have_simd) + goto end; + drmp3_cpuid(CPUInfo, 0); + if (CPUInfo[0] > 0) + { + drmp3_cpuid(CPUInfo, 1); + g_have_simd = (CPUInfo[3] & (1 << 26)) + 1; /* SSE2 */ + return g_have_simd - 1; + } + +end: + return g_have_simd - 1; +#endif +} +#elif defined(__ARM_NEON) || defined(__aarch64__) || defined(_M_ARM64) +#include +#define DRMP3_HAVE_SSE 0 +#define DRMP3_HAVE_SIMD 1 +#define DRMP3_VSTORE vst1q_f32 +#define DRMP3_VLD vld1q_f32 +#define DRMP3_VSET vmovq_n_f32 +#define DRMP3_VADD vaddq_f32 +#define DRMP3_VSUB vsubq_f32 +#define DRMP3_VMUL vmulq_f32 +#define DRMP3_VMAC(a, x, y) vmlaq_f32(a, x, y) +#define DRMP3_VMSB(a, x, y) vmlsq_f32(a, x, y) +#define DRMP3_VMUL_S(x, s) vmulq_f32(x, vmovq_n_f32(s)) +#define DRMP3_VREV(x) vcombine_f32(vget_high_f32(vrev64q_f32(x)), vget_low_f32(vrev64q_f32(x))) +typedef float32x4_t drmp3_f4; +static int drmp3_have_simd(void) +{ /* TODO: detect neon for !DR_MP3_ONLY_SIMD */ + return 1; +} +#else +#define DRMP3_HAVE_SSE 0 +#define DRMP3_HAVE_SIMD 0 +#ifdef DR_MP3_ONLY_SIMD +#error DR_MP3_ONLY_SIMD used, but SSE/NEON not enabled +#endif +#endif + +#else + +#define DRMP3_HAVE_SIMD 0 + +#endif + +#if defined(__ARM_ARCH) && (__ARM_ARCH >= 6) && !defined(__aarch64__) && !defined(_M_ARM64) +#define DRMP3_HAVE_ARMV6 1 +static __inline__ __attribute__((always_inline)) drmp3_int32 drmp3_clip_int16_arm(int32_t a) +{ + drmp3_int32 x = 0; + __asm__ ("ssat %0, #16, %1" : "=r"(x) : "r"(a)); + return x; +} +#else +#define DRMP3_HAVE_ARMV6 0 +#endif + + +typedef struct +{ + const drmp3_uint8 *buf; + int pos, limit; +} drmp3_bs; + +typedef struct +{ + float scf[3*64]; + drmp3_uint8 total_bands, stereo_bands, bitalloc[64], scfcod[64]; +} drmp3_L12_scale_info; + +typedef struct +{ + drmp3_uint8 tab_offset, code_tab_width, band_count; +} drmp3_L12_subband_alloc; + +typedef struct +{ + const drmp3_uint8 *sfbtab; + drmp3_uint16 part_23_length, big_values, scalefac_compress; + drmp3_uint8 global_gain, block_type, mixed_block_flag, n_long_sfb, n_short_sfb; + drmp3_uint8 table_select[3], region_count[3], subblock_gain[3]; + drmp3_uint8 preflag, scalefac_scale, count1_table, scfsi; +} drmp3_L3_gr_info; + +typedef struct +{ + drmp3_bs bs; + drmp3_uint8 maindata[DRMP3_MAX_BITRESERVOIR_BYTES + DRMP3_MAX_L3_FRAME_PAYLOAD_BYTES]; + drmp3_L3_gr_info gr_info[4]; + float grbuf[2][576], scf[40], syn[18 + 15][2*32]; + drmp3_uint8 ist_pos[2][39]; +} drmp3dec_scratch; + +static void drmp3_bs_init(drmp3_bs *bs, const drmp3_uint8 *data, int bytes) +{ + bs->buf = data; + bs->pos = 0; + bs->limit = bytes*8; +} + +static drmp3_uint32 drmp3_bs_get_bits(drmp3_bs *bs, int n) +{ + drmp3_uint32 next, cache = 0, s = bs->pos & 7; + int shl = n + s; + const drmp3_uint8 *p = bs->buf + (bs->pos >> 3); + if ((bs->pos += n) > bs->limit) + return 0; + next = *p++ & (255 >> s); + while ((shl -= 8) > 0) + { + cache |= next << shl; + next = *p++; + } + return cache | (next >> -shl); +} + +static int drmp3_hdr_valid(const drmp3_uint8 *h) +{ + return h[0] == 0xff && + ((h[1] & 0xF0) == 0xf0 || (h[1] & 0xFE) == 0xe2) && + (DRMP3_HDR_GET_LAYER(h) != 0) && + (DRMP3_HDR_GET_BITRATE(h) != 15) && + (DRMP3_HDR_GET_SAMPLE_RATE(h) != 3); +} + +static int drmp3_hdr_compare(const drmp3_uint8 *h1, const drmp3_uint8 *h2) +{ + return drmp3_hdr_valid(h2) && + ((h1[1] ^ h2[1]) & 0xFE) == 0 && + ((h1[2] ^ h2[2]) & 0x0C) == 0 && + !(DRMP3_HDR_IS_FREE_FORMAT(h1) ^ DRMP3_HDR_IS_FREE_FORMAT(h2)); +} + +static unsigned drmp3_hdr_bitrate_kbps(const drmp3_uint8 *h) +{ + static const drmp3_uint8 halfrate[2][3][15] = { + { { 0,4,8,12,16,20,24,28,32,40,48,56,64,72,80 }, { 0,4,8,12,16,20,24,28,32,40,48,56,64,72,80 }, { 0,16,24,28,32,40,48,56,64,72,80,88,96,112,128 } }, + { { 0,16,20,24,28,32,40,48,56,64,80,96,112,128,160 }, { 0,16,24,28,32,40,48,56,64,80,96,112,128,160,192 }, { 0,16,32,48,64,80,96,112,128,144,160,176,192,208,224 } }, + }; + return 2*halfrate[!!DRMP3_HDR_TEST_MPEG1(h)][DRMP3_HDR_GET_LAYER(h) - 1][DRMP3_HDR_GET_BITRATE(h)]; +} + +static unsigned drmp3_hdr_sample_rate_hz(const drmp3_uint8 *h) +{ + static const unsigned g_hz[3] = { 44100, 48000, 32000 }; + return g_hz[DRMP3_HDR_GET_SAMPLE_RATE(h)] >> (int)!DRMP3_HDR_TEST_MPEG1(h) >> (int)!DRMP3_HDR_TEST_NOT_MPEG25(h); +} + +static unsigned drmp3_hdr_frame_samples(const drmp3_uint8 *h) +{ + return DRMP3_HDR_IS_LAYER_1(h) ? 384 : (1152 >> (int)DRMP3_HDR_IS_FRAME_576(h)); +} + +static int drmp3_hdr_frame_bytes(const drmp3_uint8 *h, int free_format_size) +{ + int frame_bytes = drmp3_hdr_frame_samples(h)*drmp3_hdr_bitrate_kbps(h)*125/drmp3_hdr_sample_rate_hz(h); + if (DRMP3_HDR_IS_LAYER_1(h)) + { + frame_bytes &= ~3; /* slot align */ + } + return frame_bytes ? frame_bytes : free_format_size; +} + +static int drmp3_hdr_padding(const drmp3_uint8 *h) +{ + return DRMP3_HDR_TEST_PADDING(h) ? (DRMP3_HDR_IS_LAYER_1(h) ? 4 : 1) : 0; +} + +#ifndef DR_MP3_ONLY_MP3 +static const drmp3_L12_subband_alloc *drmp3_L12_subband_alloc_table(const drmp3_uint8 *hdr, drmp3_L12_scale_info *sci) +{ + const drmp3_L12_subband_alloc *alloc; + int mode = DRMP3_HDR_GET_STEREO_MODE(hdr); + int nbands, stereo_bands = (mode == DRMP3_MODE_MONO) ? 0 : (mode == DRMP3_MODE_JOINT_STEREO) ? (DRMP3_HDR_GET_STEREO_MODE_EXT(hdr) << 2) + 4 : 32; + + if (DRMP3_HDR_IS_LAYER_1(hdr)) + { + static const drmp3_L12_subband_alloc g_alloc_L1[] = { { 76, 4, 32 } }; + alloc = g_alloc_L1; + nbands = 32; + } else if (!DRMP3_HDR_TEST_MPEG1(hdr)) + { + static const drmp3_L12_subband_alloc g_alloc_L2M2[] = { { 60, 4, 4 }, { 44, 3, 7 }, { 44, 2, 19 } }; + alloc = g_alloc_L2M2; + nbands = 30; + } else + { + static const drmp3_L12_subband_alloc g_alloc_L2M1[] = { { 0, 4, 3 }, { 16, 4, 8 }, { 32, 3, 12 }, { 40, 2, 7 } }; + int sample_rate_idx = DRMP3_HDR_GET_SAMPLE_RATE(hdr); + unsigned kbps = drmp3_hdr_bitrate_kbps(hdr) >> (int)(mode != DRMP3_MODE_MONO); + if (!kbps) /* free-format */ + { + kbps = 192; + } + + alloc = g_alloc_L2M1; + nbands = 27; + if (kbps < 56) + { + static const drmp3_L12_subband_alloc g_alloc_L2M1_lowrate[] = { { 44, 4, 2 }, { 44, 3, 10 } }; + alloc = g_alloc_L2M1_lowrate; + nbands = sample_rate_idx == 2 ? 12 : 8; + } else if (kbps >= 96 && sample_rate_idx != 1) + { + nbands = 30; + } + } + + sci->total_bands = (drmp3_uint8)nbands; + sci->stereo_bands = (drmp3_uint8)DRMP3_MIN(stereo_bands, nbands); + + return alloc; +} + +static void drmp3_L12_read_scalefactors(drmp3_bs *bs, drmp3_uint8 *pba, drmp3_uint8 *scfcod, int bands, float *scf) +{ + static const float g_deq_L12[18*3] = { +#define DRMP3_DQ(x) 9.53674316e-07f/x, 7.56931807e-07f/x, 6.00777173e-07f/x + DRMP3_DQ(3),DRMP3_DQ(7),DRMP3_DQ(15),DRMP3_DQ(31),DRMP3_DQ(63),DRMP3_DQ(127),DRMP3_DQ(255),DRMP3_DQ(511),DRMP3_DQ(1023),DRMP3_DQ(2047),DRMP3_DQ(4095),DRMP3_DQ(8191),DRMP3_DQ(16383),DRMP3_DQ(32767),DRMP3_DQ(65535),DRMP3_DQ(3),DRMP3_DQ(5),DRMP3_DQ(9) + }; + int i, m; + for (i = 0; i < bands; i++) + { + float s = 0; + int ba = *pba++; + int mask = ba ? 4 + ((19 >> scfcod[i]) & 3) : 0; + for (m = 4; m; m >>= 1) + { + if (mask & m) + { + int b = drmp3_bs_get_bits(bs, 6); + s = g_deq_L12[ba*3 - 6 + b % 3]*(int)(1 << 21 >> b/3); + } + *scf++ = s; + } + } +} + +static void drmp3_L12_read_scale_info(const drmp3_uint8 *hdr, drmp3_bs *bs, drmp3_L12_scale_info *sci) +{ + static const drmp3_uint8 g_bitalloc_code_tab[] = { + 0,17, 3, 4, 5,6,7, 8,9,10,11,12,13,14,15,16, + 0,17,18, 3,19,4,5, 6,7, 8, 9,10,11,12,13,16, + 0,17,18, 3,19,4,5,16, + 0,17,18,16, + 0,17,18,19, 4,5,6, 7,8, 9,10,11,12,13,14,15, + 0,17,18, 3,19,4,5, 6,7, 8, 9,10,11,12,13,14, + 0, 2, 3, 4, 5,6,7, 8,9,10,11,12,13,14,15,16 + }; + const drmp3_L12_subband_alloc *subband_alloc = drmp3_L12_subband_alloc_table(hdr, sci); + + int i, k = 0, ba_bits = 0; + const drmp3_uint8 *ba_code_tab = g_bitalloc_code_tab; + + for (i = 0; i < sci->total_bands; i++) + { + drmp3_uint8 ba; + if (i == k) + { + k += subband_alloc->band_count; + ba_bits = subband_alloc->code_tab_width; + ba_code_tab = g_bitalloc_code_tab + subband_alloc->tab_offset; + subband_alloc++; + } + ba = ba_code_tab[drmp3_bs_get_bits(bs, ba_bits)]; + sci->bitalloc[2*i] = ba; + if (i < sci->stereo_bands) + { + ba = ba_code_tab[drmp3_bs_get_bits(bs, ba_bits)]; + } + sci->bitalloc[2*i + 1] = sci->stereo_bands ? ba : 0; + } + + for (i = 0; i < 2*sci->total_bands; i++) + { + sci->scfcod[i] = (drmp3_uint8)(sci->bitalloc[i] ? DRMP3_HDR_IS_LAYER_1(hdr) ? 2 : drmp3_bs_get_bits(bs, 2) : 6); + } + + drmp3_L12_read_scalefactors(bs, sci->bitalloc, sci->scfcod, sci->total_bands*2, sci->scf); + + for (i = sci->stereo_bands; i < sci->total_bands; i++) + { + sci->bitalloc[2*i + 1] = 0; + } +} + +static int drmp3_L12_dequantize_granule(float *grbuf, drmp3_bs *bs, drmp3_L12_scale_info *sci, int group_size) +{ + int i, j, k, choff = 576; + for (j = 0; j < 4; j++) + { + float *dst = grbuf + group_size*j; + for (i = 0; i < 2*sci->total_bands; i++) + { + int ba = sci->bitalloc[i]; + if (ba != 0) + { + if (ba < 17) + { + int half = (1 << (ba - 1)) - 1; + for (k = 0; k < group_size; k++) + { + dst[k] = (float)((int)drmp3_bs_get_bits(bs, ba) - half); + } + } else + { + unsigned mod = (2 << (ba - 17)) + 1; /* 3, 5, 9 */ + unsigned code = drmp3_bs_get_bits(bs, mod + 2 - (mod >> 3)); /* 5, 7, 10 */ + for (k = 0; k < group_size; k++, code /= mod) + { + dst[k] = (float)((int)(code % mod - mod/2)); + } + } + } + dst += choff; + choff = 18 - choff; + } + } + return group_size*4; +} + +static void drmp3_L12_apply_scf_384(drmp3_L12_scale_info *sci, const float *scf, float *dst) +{ + int i, k; + memcpy(dst + 576 + sci->stereo_bands*18, dst + sci->stereo_bands*18, (sci->total_bands - sci->stereo_bands)*18*sizeof(float)); + for (i = 0; i < sci->total_bands; i++, dst += 18, scf += 6) + { + for (k = 0; k < 12; k++) + { + dst[k + 0] *= scf[0]; + dst[k + 576] *= scf[3]; + } + } +} +#endif + +static int drmp3_L3_read_side_info(drmp3_bs *bs, drmp3_L3_gr_info *gr, const drmp3_uint8 *hdr) +{ + static const drmp3_uint8 g_scf_long[8][23] = { + { 6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54,0 }, + { 12,12,12,12,12,12,16,20,24,28,32,40,48,56,64,76,90,2,2,2,2,2,0 }, + { 6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54,0 }, + { 6,6,6,6,6,6,8,10,12,14,16,18,22,26,32,38,46,54,62,70,76,36,0 }, + { 6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54,0 }, + { 4,4,4,4,4,4,6,6,8,8,10,12,16,20,24,28,34,42,50,54,76,158,0 }, + { 4,4,4,4,4,4,6,6,6,8,10,12,16,18,22,28,34,40,46,54,54,192,0 }, + { 4,4,4,4,4,4,6,6,8,10,12,16,20,24,30,38,46,56,68,84,102,26,0 } + }; + static const drmp3_uint8 g_scf_short[8][40] = { + { 4,4,4,4,4,4,4,4,4,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,24,24,24,30,30,30,40,40,40,18,18,18,0 }, + { 8,8,8,8,8,8,8,8,8,12,12,12,16,16,16,20,20,20,24,24,24,28,28,28,36,36,36,2,2,2,2,2,2,2,2,2,26,26,26,0 }, + { 4,4,4,4,4,4,4,4,4,6,6,6,6,6,6,8,8,8,10,10,10,14,14,14,18,18,18,26,26,26,32,32,32,42,42,42,18,18,18,0 }, + { 4,4,4,4,4,4,4,4,4,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,24,24,24,32,32,32,44,44,44,12,12,12,0 }, + { 4,4,4,4,4,4,4,4,4,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,24,24,24,30,30,30,40,40,40,18,18,18,0 }, + { 4,4,4,4,4,4,4,4,4,4,4,4,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,22,22,22,30,30,30,56,56,56,0 }, + { 4,4,4,4,4,4,4,4,4,4,4,4,6,6,6,6,6,6,10,10,10,12,12,12,14,14,14,16,16,16,20,20,20,26,26,26,66,66,66,0 }, + { 4,4,4,4,4,4,4,4,4,4,4,4,6,6,6,8,8,8,12,12,12,16,16,16,20,20,20,26,26,26,34,34,34,42,42,42,12,12,12,0 } + }; + static const drmp3_uint8 g_scf_mixed[8][40] = { + { 6,6,6,6,6,6,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,24,24,24,30,30,30,40,40,40,18,18,18,0 }, + { 12,12,12,4,4,4,8,8,8,12,12,12,16,16,16,20,20,20,24,24,24,28,28,28,36,36,36,2,2,2,2,2,2,2,2,2,26,26,26,0 }, + { 6,6,6,6,6,6,6,6,6,6,6,6,8,8,8,10,10,10,14,14,14,18,18,18,26,26,26,32,32,32,42,42,42,18,18,18,0 }, + { 6,6,6,6,6,6,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,24,24,24,32,32,32,44,44,44,12,12,12,0 }, + { 6,6,6,6,6,6,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,24,24,24,30,30,30,40,40,40,18,18,18,0 }, + { 4,4,4,4,4,4,6,6,4,4,4,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,22,22,22,30,30,30,56,56,56,0 }, + { 4,4,4,4,4,4,6,6,4,4,4,6,6,6,6,6,6,10,10,10,12,12,12,14,14,14,16,16,16,20,20,20,26,26,26,66,66,66,0 }, + { 4,4,4,4,4,4,6,6,4,4,4,6,6,6,8,8,8,12,12,12,16,16,16,20,20,20,26,26,26,34,34,34,42,42,42,12,12,12,0 } + }; + + unsigned tables, scfsi = 0; + int main_data_begin, part_23_sum = 0; + int gr_count = DRMP3_HDR_IS_MONO(hdr) ? 1 : 2; + int sr_idx = DRMP3_HDR_GET_MY_SAMPLE_RATE(hdr); sr_idx -= (sr_idx != 0); + + if (DRMP3_HDR_TEST_MPEG1(hdr)) + { + gr_count *= 2; + main_data_begin = drmp3_bs_get_bits(bs, 9); + scfsi = drmp3_bs_get_bits(bs, 7 + gr_count); + } else + { + main_data_begin = drmp3_bs_get_bits(bs, 8 + gr_count) >> gr_count; + } + + do + { + if (DRMP3_HDR_IS_MONO(hdr)) + { + scfsi <<= 4; + } + gr->part_23_length = (drmp3_uint16)drmp3_bs_get_bits(bs, 12); + part_23_sum += gr->part_23_length; + gr->big_values = (drmp3_uint16)drmp3_bs_get_bits(bs, 9); + if (gr->big_values > 288) + { + return -1; + } + gr->global_gain = (drmp3_uint8)drmp3_bs_get_bits(bs, 8); + gr->scalefac_compress = (drmp3_uint16)drmp3_bs_get_bits(bs, DRMP3_HDR_TEST_MPEG1(hdr) ? 4 : 9); + gr->sfbtab = g_scf_long[sr_idx]; + gr->n_long_sfb = 22; + gr->n_short_sfb = 0; + if (drmp3_bs_get_bits(bs, 1)) + { + gr->block_type = (drmp3_uint8)drmp3_bs_get_bits(bs, 2); + if (!gr->block_type) + { + return -1; + } + gr->mixed_block_flag = (drmp3_uint8)drmp3_bs_get_bits(bs, 1); + gr->region_count[0] = 7; + gr->region_count[1] = 255; + if (gr->block_type == DRMP3_SHORT_BLOCK_TYPE) + { + scfsi &= 0x0F0F; + if (!gr->mixed_block_flag) + { + gr->region_count[0] = 8; + gr->sfbtab = g_scf_short[sr_idx]; + gr->n_long_sfb = 0; + gr->n_short_sfb = 39; + } else + { + gr->sfbtab = g_scf_mixed[sr_idx]; + gr->n_long_sfb = DRMP3_HDR_TEST_MPEG1(hdr) ? 8 : 6; + gr->n_short_sfb = 30; + } + } + tables = drmp3_bs_get_bits(bs, 10); + tables <<= 5; + gr->subblock_gain[0] = (drmp3_uint8)drmp3_bs_get_bits(bs, 3); + gr->subblock_gain[1] = (drmp3_uint8)drmp3_bs_get_bits(bs, 3); + gr->subblock_gain[2] = (drmp3_uint8)drmp3_bs_get_bits(bs, 3); + } else + { + gr->block_type = 0; + gr->mixed_block_flag = 0; + tables = drmp3_bs_get_bits(bs, 15); + gr->region_count[0] = (drmp3_uint8)drmp3_bs_get_bits(bs, 4); + gr->region_count[1] = (drmp3_uint8)drmp3_bs_get_bits(bs, 3); + gr->region_count[2] = 255; + } + gr->table_select[0] = (drmp3_uint8)(tables >> 10); + gr->table_select[1] = (drmp3_uint8)((tables >> 5) & 31); + gr->table_select[2] = (drmp3_uint8)((tables) & 31); + gr->preflag = (drmp3_uint8)(DRMP3_HDR_TEST_MPEG1(hdr) ? drmp3_bs_get_bits(bs, 1) : (gr->scalefac_compress >= 500)); + gr->scalefac_scale = (drmp3_uint8)drmp3_bs_get_bits(bs, 1); + gr->count1_table = (drmp3_uint8)drmp3_bs_get_bits(bs, 1); + gr->scfsi = (drmp3_uint8)((scfsi >> 12) & 15); + scfsi <<= 4; + gr++; + } while(--gr_count); + + if (part_23_sum + bs->pos > bs->limit + main_data_begin*8) + { + return -1; + } + + return main_data_begin; +} + +static void drmp3_L3_read_scalefactors(drmp3_uint8 *scf, drmp3_uint8 *ist_pos, const drmp3_uint8 *scf_size, const drmp3_uint8 *scf_count, drmp3_bs *bitbuf, int scfsi) +{ + int i, k; + for (i = 0; i < 4 && scf_count[i]; i++, scfsi *= 2) + { + int cnt = scf_count[i]; + if (scfsi & 8) + { + memcpy(scf, ist_pos, cnt); + } else + { + int bits = scf_size[i]; + if (!bits) + { + memset(scf, 0, cnt); + memset(ist_pos, 0, cnt); + } else + { + int max_scf = (scfsi < 0) ? (1 << bits) - 1 : -1; + for (k = 0; k < cnt; k++) + { + int s = drmp3_bs_get_bits(bitbuf, bits); + ist_pos[k] = (drmp3_uint8)(s == max_scf ? -1 : s); + scf[k] = (drmp3_uint8)s; + } + } + } + ist_pos += cnt; + scf += cnt; + } + scf[0] = scf[1] = scf[2] = 0; +} + +static float drmp3_L3_ldexp_q2(float y, int exp_q2) +{ + static const float g_expfrac[4] = { 9.31322575e-10f,7.83145814e-10f,6.58544508e-10f,5.53767716e-10f }; + int e; + do + { + e = DRMP3_MIN(30*4, exp_q2); + y *= g_expfrac[e & 3]*(1 << 30 >> (e >> 2)); + } while ((exp_q2 -= e) > 0); + return y; +} + +static void drmp3_L3_decode_scalefactors(const drmp3_uint8 *hdr, drmp3_uint8 *ist_pos, drmp3_bs *bs, const drmp3_L3_gr_info *gr, float *scf, int ch) +{ + static const drmp3_uint8 g_scf_partitions[3][28] = { + { 6,5,5, 5,6,5,5,5,6,5, 7,3,11,10,0,0, 7, 7, 7,0, 6, 6,6,3, 8, 8,5,0 }, + { 8,9,6,12,6,9,9,9,6,9,12,6,15,18,0,0, 6,15,12,0, 6,12,9,6, 6,18,9,0 }, + { 9,9,6,12,9,9,9,9,9,9,12,6,18,18,0,0,12,12,12,0,12, 9,9,6,15,12,9,0 } + }; + const drmp3_uint8 *scf_partition = g_scf_partitions[!!gr->n_short_sfb + !gr->n_long_sfb]; + drmp3_uint8 scf_size[4], iscf[40]; + int i, scf_shift = gr->scalefac_scale + 1, gain_exp, scfsi = gr->scfsi; + float gain; + + if (DRMP3_HDR_TEST_MPEG1(hdr)) + { + static const drmp3_uint8 g_scfc_decode[16] = { 0,1,2,3, 12,5,6,7, 9,10,11,13, 14,15,18,19 }; + int part = g_scfc_decode[gr->scalefac_compress]; + scf_size[1] = scf_size[0] = (drmp3_uint8)(part >> 2); + scf_size[3] = scf_size[2] = (drmp3_uint8)(part & 3); + } else + { + static const drmp3_uint8 g_mod[6*4] = { 5,5,4,4,5,5,4,1,4,3,1,1,5,6,6,1,4,4,4,1,4,3,1,1 }; + int k, modprod, sfc, ist = DRMP3_HDR_TEST_I_STEREO(hdr) && ch; + sfc = gr->scalefac_compress >> ist; + for (k = ist*3*4; sfc >= 0; sfc -= modprod, k += 4) + { + for (modprod = 1, i = 3; i >= 0; i--) + { + scf_size[i] = (drmp3_uint8)(sfc / modprod % g_mod[k + i]); + modprod *= g_mod[k + i]; + } + } + scf_partition += k; + scfsi = -16; + } + drmp3_L3_read_scalefactors(iscf, ist_pos, scf_size, scf_partition, bs, scfsi); + + if (gr->n_short_sfb) + { + int sh = 3 - scf_shift; + for (i = 0; i < gr->n_short_sfb; i += 3) + { + iscf[gr->n_long_sfb + i + 0] = (drmp3_uint8)(iscf[gr->n_long_sfb + i + 0] + (gr->subblock_gain[0] << sh)); + iscf[gr->n_long_sfb + i + 1] = (drmp3_uint8)(iscf[gr->n_long_sfb + i + 1] + (gr->subblock_gain[1] << sh)); + iscf[gr->n_long_sfb + i + 2] = (drmp3_uint8)(iscf[gr->n_long_sfb + i + 2] + (gr->subblock_gain[2] << sh)); + } + } else if (gr->preflag) + { + static const drmp3_uint8 g_preamp[10] = { 1,1,1,1,2,2,3,3,3,2 }; + for (i = 0; i < 10; i++) + { + iscf[11 + i] = (drmp3_uint8)(iscf[11 + i] + g_preamp[i]); + } + } + + gain_exp = gr->global_gain + DRMP3_BITS_DEQUANTIZER_OUT*4 - 210 - (DRMP3_HDR_IS_MS_STEREO(hdr) ? 2 : 0); + gain = drmp3_L3_ldexp_q2(1 << (DRMP3_MAX_SCFI/4), DRMP3_MAX_SCFI - gain_exp); + for (i = 0; i < (int)(gr->n_long_sfb + gr->n_short_sfb); i++) + { + scf[i] = drmp3_L3_ldexp_q2(gain, iscf[i] << scf_shift); + } +} + +static const float g_drmp3_pow43[129 + 16] = { + 0,-1,-2.519842f,-4.326749f,-6.349604f,-8.549880f,-10.902724f,-13.390518f,-16.000000f,-18.720754f,-21.544347f,-24.463781f,-27.473142f,-30.567351f,-33.741992f,-36.993181f, + 0,1,2.519842f,4.326749f,6.349604f,8.549880f,10.902724f,13.390518f,16.000000f,18.720754f,21.544347f,24.463781f,27.473142f,30.567351f,33.741992f,36.993181f,40.317474f,43.711787f,47.173345f,50.699631f,54.288352f,57.937408f,61.644865f,65.408941f,69.227979f,73.100443f,77.024898f,81.000000f,85.024491f,89.097188f,93.216975f,97.382800f,101.593667f,105.848633f,110.146801f,114.487321f,118.869381f,123.292209f,127.755065f,132.257246f,136.798076f,141.376907f,145.993119f,150.646117f,155.335327f,160.060199f,164.820202f,169.614826f,174.443577f,179.305980f,184.201575f,189.129918f,194.090580f,199.083145f,204.107210f,209.162385f,214.248292f,219.364564f,224.510845f,229.686789f,234.892058f,240.126328f,245.389280f,250.680604f,256.000000f,261.347174f,266.721841f,272.123723f,277.552547f,283.008049f,288.489971f,293.998060f,299.532071f,305.091761f,310.676898f,316.287249f,321.922592f,327.582707f,333.267377f,338.976394f,344.709550f,350.466646f,356.247482f,362.051866f,367.879608f,373.730522f,379.604427f,385.501143f,391.420496f,397.362314f,403.326427f,409.312672f,415.320884f,421.350905f,427.402579f,433.475750f,439.570269f,445.685987f,451.822757f,457.980436f,464.158883f,470.357960f,476.577530f,482.817459f,489.077615f,495.357868f,501.658090f,507.978156f,514.317941f,520.677324f,527.056184f,533.454404f,539.871867f,546.308458f,552.764065f,559.238575f,565.731879f,572.243870f,578.774440f,585.323483f,591.890898f,598.476581f,605.080431f,611.702349f,618.342238f,625.000000f,631.675540f,638.368763f,645.079578f +}; + +static float drmp3_L3_pow_43(int x) +{ + float frac; + int sign, mult = 256; + + if (x < 129) + { + return g_drmp3_pow43[16 + x]; + } + + if (x < 1024) + { + mult = 16; + x <<= 3; + } + + sign = 2*x & 64; + frac = (float)((x & 63) - sign) / ((x & ~63) + sign); + return g_drmp3_pow43[16 + ((x + sign) >> 6)]*(1.f + frac*((4.f/3) + frac*(2.f/9)))*mult; +} + +static void drmp3_L3_huffman(float *dst, drmp3_bs *bs, const drmp3_L3_gr_info *gr_info, const float *scf, int layer3gr_limit) +{ + static const drmp3_int16 tabs[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 785,785,785,785,784,784,784,784,513,513,513,513,513,513,513,513,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256, + -255,1313,1298,1282,785,785,785,785,784,784,784,784,769,769,769,769,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,290,288, + -255,1313,1298,1282,769,769,769,769,529,529,529,529,529,529,529,529,528,528,528,528,528,528,528,528,512,512,512,512,512,512,512,512,290,288, + -253,-318,-351,-367,785,785,785,785,784,784,784,784,769,769,769,769,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,819,818,547,547,275,275,275,275,561,560,515,546,289,274,288,258, + -254,-287,1329,1299,1314,1312,1057,1057,1042,1042,1026,1026,784,784,784,784,529,529,529,529,529,529,529,529,769,769,769,769,768,768,768,768,563,560,306,306,291,259, + -252,-413,-477,-542,1298,-575,1041,1041,784,784,784,784,769,769,769,769,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,-383,-399,1107,1092,1106,1061,849,849,789,789,1104,1091,773,773,1076,1075,341,340,325,309,834,804,577,577,532,532,516,516,832,818,803,816,561,561,531,531,515,546,289,289,288,258, + -252,-429,-493,-559,1057,1057,1042,1042,529,529,529,529,529,529,529,529,784,784,784,784,769,769,769,769,512,512,512,512,512,512,512,512,-382,1077,-415,1106,1061,1104,849,849,789,789,1091,1076,1029,1075,834,834,597,581,340,340,339,324,804,833,532,532,832,772,818,803,817,787,816,771,290,290,290,290,288,258, + -253,-349,-414,-447,-463,1329,1299,-479,1314,1312,1057,1057,1042,1042,1026,1026,785,785,785,785,784,784,784,784,769,769,769,769,768,768,768,768,-319,851,821,-335,836,850,805,849,341,340,325,336,533,533,579,579,564,564,773,832,578,548,563,516,321,276,306,291,304,259, + -251,-572,-733,-830,-863,-879,1041,1041,784,784,784,784,769,769,769,769,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,-511,-527,-543,1396,1351,1381,1366,1395,1335,1380,-559,1334,1138,1138,1063,1063,1350,1392,1031,1031,1062,1062,1364,1363,1120,1120,1333,1348,881,881,881,881,375,374,359,373,343,358,341,325,791,791,1123,1122,-703,1105,1045,-719,865,865,790,790,774,774,1104,1029,338,293,323,308,-799,-815,833,788,772,818,803,816,322,292,307,320,561,531,515,546,289,274,288,258, + -251,-525,-605,-685,-765,-831,-846,1298,1057,1057,1312,1282,785,785,785,785,784,784,784,784,769,769,769,769,512,512,512,512,512,512,512,512,1399,1398,1383,1367,1382,1396,1351,-511,1381,1366,1139,1139,1079,1079,1124,1124,1364,1349,1363,1333,882,882,882,882,807,807,807,807,1094,1094,1136,1136,373,341,535,535,881,775,867,822,774,-591,324,338,-671,849,550,550,866,864,609,609,293,336,534,534,789,835,773,-751,834,804,308,307,833,788,832,772,562,562,547,547,305,275,560,515,290,290, + -252,-397,-477,-557,-622,-653,-719,-735,-750,1329,1299,1314,1057,1057,1042,1042,1312,1282,1024,1024,785,785,785,785,784,784,784,784,769,769,769,769,-383,1127,1141,1111,1126,1140,1095,1110,869,869,883,883,1079,1109,882,882,375,374,807,868,838,881,791,-463,867,822,368,263,852,837,836,-543,610,610,550,550,352,336,534,534,865,774,851,821,850,805,593,533,579,564,773,832,578,578,548,548,577,577,307,276,306,291,516,560,259,259, + -250,-2107,-2507,-2764,-2909,-2974,-3007,-3023,1041,1041,1040,1040,769,769,769,769,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,-767,-1052,-1213,-1277,-1358,-1405,-1469,-1535,-1550,-1582,-1614,-1647,-1662,-1694,-1726,-1759,-1774,-1807,-1822,-1854,-1886,1565,-1919,-1935,-1951,-1967,1731,1730,1580,1717,-1983,1729,1564,-1999,1548,-2015,-2031,1715,1595,-2047,1714,-2063,1610,-2079,1609,-2095,1323,1323,1457,1457,1307,1307,1712,1547,1641,1700,1699,1594,1685,1625,1442,1442,1322,1322,-780,-973,-910,1279,1278,1277,1262,1276,1261,1275,1215,1260,1229,-959,974,974,989,989,-943,735,478,478,495,463,506,414,-1039,1003,958,1017,927,942,987,957,431,476,1272,1167,1228,-1183,1256,-1199,895,895,941,941,1242,1227,1212,1135,1014,1014,490,489,503,487,910,1013,985,925,863,894,970,955,1012,847,-1343,831,755,755,984,909,428,366,754,559,-1391,752,486,457,924,997,698,698,983,893,740,740,908,877,739,739,667,667,953,938,497,287,271,271,683,606,590,712,726,574,302,302,738,736,481,286,526,725,605,711,636,724,696,651,589,681,666,710,364,467,573,695,466,466,301,465,379,379,709,604,665,679,316,316,634,633,436,436,464,269,424,394,452,332,438,363,347,408,393,448,331,422,362,407,392,421,346,406,391,376,375,359,1441,1306,-2367,1290,-2383,1337,-2399,-2415,1426,1321,-2431,1411,1336,-2447,-2463,-2479,1169,1169,1049,1049,1424,1289,1412,1352,1319,-2495,1154,1154,1064,1064,1153,1153,416,390,360,404,403,389,344,374,373,343,358,372,327,357,342,311,356,326,1395,1394,1137,1137,1047,1047,1365,1392,1287,1379,1334,1364,1349,1378,1318,1363,792,792,792,792,1152,1152,1032,1032,1121,1121,1046,1046,1120,1120,1030,1030,-2895,1106,1061,1104,849,849,789,789,1091,1076,1029,1090,1060,1075,833,833,309,324,532,532,832,772,818,803,561,561,531,560,515,546,289,274,288,258, + -250,-1179,-1579,-1836,-1996,-2124,-2253,-2333,-2413,-2477,-2542,-2574,-2607,-2622,-2655,1314,1313,1298,1312,1282,785,785,785,785,1040,1040,1025,1025,768,768,768,768,-766,-798,-830,-862,-895,-911,-927,-943,-959,-975,-991,-1007,-1023,-1039,-1055,-1070,1724,1647,-1103,-1119,1631,1767,1662,1738,1708,1723,-1135,1780,1615,1779,1599,1677,1646,1778,1583,-1151,1777,1567,1737,1692,1765,1722,1707,1630,1751,1661,1764,1614,1736,1676,1763,1750,1645,1598,1721,1691,1762,1706,1582,1761,1566,-1167,1749,1629,767,766,751,765,494,494,735,764,719,749,734,763,447,447,748,718,477,506,431,491,446,476,461,505,415,430,475,445,504,399,460,489,414,503,383,474,429,459,502,502,746,752,488,398,501,473,413,472,486,271,480,270,-1439,-1455,1357,-1471,-1487,-1503,1341,1325,-1519,1489,1463,1403,1309,-1535,1372,1448,1418,1476,1356,1462,1387,-1551,1475,1340,1447,1402,1386,-1567,1068,1068,1474,1461,455,380,468,440,395,425,410,454,364,467,466,464,453,269,409,448,268,432,1371,1473,1432,1417,1308,1460,1355,1446,1459,1431,1083,1083,1401,1416,1458,1445,1067,1067,1370,1457,1051,1051,1291,1430,1385,1444,1354,1415,1400,1443,1082,1082,1173,1113,1186,1066,1185,1050,-1967,1158,1128,1172,1097,1171,1081,-1983,1157,1112,416,266,375,400,1170,1142,1127,1065,793,793,1169,1033,1156,1096,1141,1111,1155,1080,1126,1140,898,898,808,808,897,897,792,792,1095,1152,1032,1125,1110,1139,1079,1124,882,807,838,881,853,791,-2319,867,368,263,822,852,837,866,806,865,-2399,851,352,262,534,534,821,836,594,594,549,549,593,593,533,533,848,773,579,579,564,578,548,563,276,276,577,576,306,291,516,560,305,305,275,259, + -251,-892,-2058,-2620,-2828,-2957,-3023,-3039,1041,1041,1040,1040,769,769,769,769,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,-511,-527,-543,-559,1530,-575,-591,1528,1527,1407,1526,1391,1023,1023,1023,1023,1525,1375,1268,1268,1103,1103,1087,1087,1039,1039,1523,-604,815,815,815,815,510,495,509,479,508,463,507,447,431,505,415,399,-734,-782,1262,-815,1259,1244,-831,1258,1228,-847,-863,1196,-879,1253,987,987,748,-767,493,493,462,477,414,414,686,669,478,446,461,445,474,429,487,458,412,471,1266,1264,1009,1009,799,799,-1019,-1276,-1452,-1581,-1677,-1757,-1821,-1886,-1933,-1997,1257,1257,1483,1468,1512,1422,1497,1406,1467,1496,1421,1510,1134,1134,1225,1225,1466,1451,1374,1405,1252,1252,1358,1480,1164,1164,1251,1251,1238,1238,1389,1465,-1407,1054,1101,-1423,1207,-1439,830,830,1248,1038,1237,1117,1223,1148,1236,1208,411,426,395,410,379,269,1193,1222,1132,1235,1221,1116,976,976,1192,1162,1177,1220,1131,1191,963,963,-1647,961,780,-1663,558,558,994,993,437,408,393,407,829,978,813,797,947,-1743,721,721,377,392,844,950,828,890,706,706,812,859,796,960,948,843,934,874,571,571,-1919,690,555,689,421,346,539,539,944,779,918,873,932,842,903,888,570,570,931,917,674,674,-2575,1562,-2591,1609,-2607,1654,1322,1322,1441,1441,1696,1546,1683,1593,1669,1624,1426,1426,1321,1321,1639,1680,1425,1425,1305,1305,1545,1668,1608,1623,1667,1592,1638,1666,1320,1320,1652,1607,1409,1409,1304,1304,1288,1288,1664,1637,1395,1395,1335,1335,1622,1636,1394,1394,1319,1319,1606,1621,1392,1392,1137,1137,1137,1137,345,390,360,375,404,373,1047,-2751,-2767,-2783,1062,1121,1046,-2799,1077,-2815,1106,1061,789,789,1105,1104,263,355,310,340,325,354,352,262,339,324,1091,1076,1029,1090,1060,1075,833,833,788,788,1088,1028,818,818,803,803,561,561,531,531,816,771,546,546,289,274,288,258, + -253,-317,-381,-446,-478,-509,1279,1279,-811,-1179,-1451,-1756,-1900,-2028,-2189,-2253,-2333,-2414,-2445,-2511,-2526,1313,1298,-2559,1041,1041,1040,1040,1025,1025,1024,1024,1022,1007,1021,991,1020,975,1019,959,687,687,1018,1017,671,671,655,655,1016,1015,639,639,758,758,623,623,757,607,756,591,755,575,754,559,543,543,1009,783,-575,-621,-685,-749,496,-590,750,749,734,748,974,989,1003,958,988,973,1002,942,987,957,972,1001,926,986,941,971,956,1000,910,985,925,999,894,970,-1071,-1087,-1102,1390,-1135,1436,1509,1451,1374,-1151,1405,1358,1480,1420,-1167,1507,1494,1389,1342,1465,1435,1450,1326,1505,1310,1493,1373,1479,1404,1492,1464,1419,428,443,472,397,736,526,464,464,486,457,442,471,484,482,1357,1449,1434,1478,1388,1491,1341,1490,1325,1489,1463,1403,1309,1477,1372,1448,1418,1433,1476,1356,1462,1387,-1439,1475,1340,1447,1402,1474,1324,1461,1371,1473,269,448,1432,1417,1308,1460,-1711,1459,-1727,1441,1099,1099,1446,1386,1431,1401,-1743,1289,1083,1083,1160,1160,1458,1445,1067,1067,1370,1457,1307,1430,1129,1129,1098,1098,268,432,267,416,266,400,-1887,1144,1187,1082,1173,1113,1186,1066,1050,1158,1128,1143,1172,1097,1171,1081,420,391,1157,1112,1170,1142,1127,1065,1169,1049,1156,1096,1141,1111,1155,1080,1126,1154,1064,1153,1140,1095,1048,-2159,1125,1110,1137,-2175,823,823,1139,1138,807,807,384,264,368,263,868,838,853,791,867,822,852,837,866,806,865,790,-2319,851,821,836,352,262,850,805,849,-2399,533,533,835,820,336,261,578,548,563,577,532,532,832,772,562,562,547,547,305,275,560,515,290,290,288,258 }; + static const drmp3_uint8 tab32[] = { 130,162,193,209,44,28,76,140,9,9,9,9,9,9,9,9,190,254,222,238,126,94,157,157,109,61,173,205}; + static const drmp3_uint8 tab33[] = { 252,236,220,204,188,172,156,140,124,108,92,76,60,44,28,12 }; + static const drmp3_int16 tabindex[2*16] = { 0,32,64,98,0,132,180,218,292,364,426,538,648,746,0,1126,1460,1460,1460,1460,1460,1460,1460,1460,1842,1842,1842,1842,1842,1842,1842,1842 }; + static const drmp3_uint8 g_linbits[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,6,8,10,13,4,5,6,7,8,9,11,13 }; + +#define DRMP3_PEEK_BITS(n) (bs_cache >> (32 - n)) +#define DRMP3_FLUSH_BITS(n) { bs_cache <<= (n); bs_sh += (n); } +#define DRMP3_CHECK_BITS while (bs_sh >= 0) { bs_cache |= (drmp3_uint32)*bs_next_ptr++ << bs_sh; bs_sh -= 8; } +#define DRMP3_BSPOS ((bs_next_ptr - bs->buf)*8 - 24 + bs_sh) + + float one = 0.0f; + int ireg = 0, big_val_cnt = gr_info->big_values; + const drmp3_uint8 *sfb = gr_info->sfbtab; + const drmp3_uint8 *bs_next_ptr = bs->buf + bs->pos/8; + drmp3_uint32 bs_cache = (((bs_next_ptr[0]*256u + bs_next_ptr[1])*256u + bs_next_ptr[2])*256u + bs_next_ptr[3]) << (bs->pos & 7); + int pairs_to_decode, np, bs_sh = (bs->pos & 7) - 8; + bs_next_ptr += 4; + + while (big_val_cnt > 0) + { + int tab_num = gr_info->table_select[ireg]; + int sfb_cnt = gr_info->region_count[ireg++]; + const drmp3_int16 *codebook = tabs + tabindex[tab_num]; + int linbits = g_linbits[tab_num]; + if (linbits) + { + do + { + np = *sfb++ / 2; + pairs_to_decode = DRMP3_MIN(big_val_cnt, np); + one = *scf++; + do + { + int j, w = 5; + int leaf = codebook[DRMP3_PEEK_BITS(w)]; + while (leaf < 0) + { + DRMP3_FLUSH_BITS(w); + w = leaf & 7; + leaf = codebook[DRMP3_PEEK_BITS(w) - (leaf >> 3)]; + } + DRMP3_FLUSH_BITS(leaf >> 8); + + for (j = 0; j < 2; j++, dst++, leaf >>= 4) + { + int lsb = leaf & 0x0F; + if (lsb == 15) + { + lsb += DRMP3_PEEK_BITS(linbits); + DRMP3_FLUSH_BITS(linbits); + DRMP3_CHECK_BITS; + *dst = one*drmp3_L3_pow_43(lsb)*((drmp3_int32)bs_cache < 0 ? -1: 1); + } else + { + *dst = g_drmp3_pow43[16 + lsb - 16*(bs_cache >> 31)]*one; + } + DRMP3_FLUSH_BITS(lsb ? 1 : 0); + } + DRMP3_CHECK_BITS; + } while (--pairs_to_decode); + } while ((big_val_cnt -= np) > 0 && --sfb_cnt >= 0); + } else + { + do + { + np = *sfb++ / 2; + pairs_to_decode = DRMP3_MIN(big_val_cnt, np); + one = *scf++; + do + { + int j, w = 5; + int leaf = codebook[DRMP3_PEEK_BITS(w)]; + while (leaf < 0) + { + DRMP3_FLUSH_BITS(w); + w = leaf & 7; + leaf = codebook[DRMP3_PEEK_BITS(w) - (leaf >> 3)]; + } + DRMP3_FLUSH_BITS(leaf >> 8); + + for (j = 0; j < 2; j++, dst++, leaf >>= 4) + { + int lsb = leaf & 0x0F; + *dst = g_drmp3_pow43[16 + lsb - 16*(bs_cache >> 31)]*one; + DRMP3_FLUSH_BITS(lsb ? 1 : 0); + } + DRMP3_CHECK_BITS; + } while (--pairs_to_decode); + } while ((big_val_cnt -= np) > 0 && --sfb_cnt >= 0); + } + } + + for (np = 1 - big_val_cnt;; dst += 4) + { + const drmp3_uint8 *codebook_count1 = (gr_info->count1_table) ? tab33 : tab32; + int leaf = codebook_count1[DRMP3_PEEK_BITS(4)]; + if (!(leaf & 8)) + { + leaf = codebook_count1[(leaf >> 3) + (bs_cache << 4 >> (32 - (leaf & 3)))]; + } + DRMP3_FLUSH_BITS(leaf & 7); + if (DRMP3_BSPOS > layer3gr_limit) + { + break; + } +#define DRMP3_RELOAD_SCALEFACTOR if (!--np) { np = *sfb++/2; if (!np) break; one = *scf++; } +#define DRMP3_DEQ_COUNT1(s) if (leaf & (128 >> s)) { dst[s] = ((drmp3_int32)bs_cache < 0) ? -one : one; DRMP3_FLUSH_BITS(1) } + DRMP3_RELOAD_SCALEFACTOR; + DRMP3_DEQ_COUNT1(0); + DRMP3_DEQ_COUNT1(1); + DRMP3_RELOAD_SCALEFACTOR; + DRMP3_DEQ_COUNT1(2); + DRMP3_DEQ_COUNT1(3); + DRMP3_CHECK_BITS; + } + + bs->pos = layer3gr_limit; +} + +static void drmp3_L3_midside_stereo(float *left, int n) +{ + int i = 0; + float *right = left + 576; +#if DRMP3_HAVE_SIMD + if (drmp3_have_simd()) for (; i < n - 3; i += 4) + { + drmp3_f4 vl = DRMP3_VLD(left + i); + drmp3_f4 vr = DRMP3_VLD(right + i); + DRMP3_VSTORE(left + i, DRMP3_VADD(vl, vr)); + DRMP3_VSTORE(right + i, DRMP3_VSUB(vl, vr)); + } +#endif + for (; i < n; i++) + { + float a = left[i]; + float b = right[i]; + left[i] = a + b; + right[i] = a - b; + } +} + +static void drmp3_L3_intensity_stereo_band(float *left, int n, float kl, float kr) +{ + int i; + for (i = 0; i < n; i++) + { + left[i + 576] = left[i]*kr; + left[i] = left[i]*kl; + } +} + +static void drmp3_L3_stereo_top_band(const float *right, const drmp3_uint8 *sfb, int nbands, int max_band[3]) +{ + int i, k; + + max_band[0] = max_band[1] = max_band[2] = -1; + + for (i = 0; i < nbands; i++) + { + for (k = 0; k < sfb[i]; k += 2) + { + if (right[k] != 0 || right[k + 1] != 0) + { + max_band[i % 3] = i; + break; + } + } + right += sfb[i]; + } +} + +static void drmp3_L3_stereo_process(float *left, const drmp3_uint8 *ist_pos, const drmp3_uint8 *sfb, const drmp3_uint8 *hdr, int max_band[3], int mpeg2_sh) +{ + static const float g_pan[7*2] = { 0,1,0.21132487f,0.78867513f,0.36602540f,0.63397460f,0.5f,0.5f,0.63397460f,0.36602540f,0.78867513f,0.21132487f,1,0 }; + unsigned i, max_pos = DRMP3_HDR_TEST_MPEG1(hdr) ? 7 : 64; + + for (i = 0; sfb[i]; i++) + { + unsigned ipos = ist_pos[i]; + if ((int)i > max_band[i % 3] && ipos < max_pos) + { + float kl, kr, s = DRMP3_HDR_TEST_MS_STEREO(hdr) ? 1.41421356f : 1; + if (DRMP3_HDR_TEST_MPEG1(hdr)) + { + kl = g_pan[2*ipos]; + kr = g_pan[2*ipos + 1]; + } else + { + kl = 1; + kr = drmp3_L3_ldexp_q2(1, (ipos + 1) >> 1 << mpeg2_sh); + if (ipos & 1) + { + kl = kr; + kr = 1; + } + } + drmp3_L3_intensity_stereo_band(left, sfb[i], kl*s, kr*s); + } else if (DRMP3_HDR_TEST_MS_STEREO(hdr)) + { + drmp3_L3_midside_stereo(left, sfb[i]); + } + left += sfb[i]; + } +} + +static void drmp3_L3_intensity_stereo(float *left, drmp3_uint8 *ist_pos, const drmp3_L3_gr_info *gr, const drmp3_uint8 *hdr) +{ + int max_band[3], n_sfb = gr->n_long_sfb + gr->n_short_sfb; + int i, max_blocks = gr->n_short_sfb ? 3 : 1; + + drmp3_L3_stereo_top_band(left + 576, gr->sfbtab, n_sfb, max_band); + if (gr->n_long_sfb) + { + max_band[0] = max_band[1] = max_band[2] = DRMP3_MAX(DRMP3_MAX(max_band[0], max_band[1]), max_band[2]); + } + for (i = 0; i < max_blocks; i++) + { + int default_pos = DRMP3_HDR_TEST_MPEG1(hdr) ? 3 : 0; + int itop = n_sfb - max_blocks + i; + int prev = itop - max_blocks; + ist_pos[itop] = (drmp3_uint8)(max_band[i] >= prev ? default_pos : ist_pos[prev]); + } + drmp3_L3_stereo_process(left, ist_pos, gr->sfbtab, hdr, max_band, gr[1].scalefac_compress & 1); +} + +static void drmp3_L3_reorder(float *grbuf, float *scratch, const drmp3_uint8 *sfb) +{ + int i, len; + float *src = grbuf, *dst = scratch; + + for (;0 != (len = *sfb); sfb += 3, src += 2*len) + { + for (i = 0; i < len; i++, src++) + { + *dst++ = src[0*len]; + *dst++ = src[1*len]; + *dst++ = src[2*len]; + } + } + memcpy(grbuf, scratch, (dst - scratch)*sizeof(float)); +} + +static void drmp3_L3_antialias(float *grbuf, int nbands) +{ + static const float g_aa[2][8] = { + {0.85749293f,0.88174200f,0.94962865f,0.98331459f,0.99551782f,0.99916056f,0.99989920f,0.99999316f}, + {0.51449576f,0.47173197f,0.31337745f,0.18191320f,0.09457419f,0.04096558f,0.01419856f,0.00369997f} + }; + + for (; nbands > 0; nbands--, grbuf += 18) + { + int i = 0; +#if DRMP3_HAVE_SIMD + if (drmp3_have_simd()) for (; i < 8; i += 4) + { + drmp3_f4 vu = DRMP3_VLD(grbuf + 18 + i); + drmp3_f4 vd = DRMP3_VLD(grbuf + 14 - i); + drmp3_f4 vc0 = DRMP3_VLD(g_aa[0] + i); + drmp3_f4 vc1 = DRMP3_VLD(g_aa[1] + i); + vd = DRMP3_VREV(vd); + DRMP3_VSTORE(grbuf + 18 + i, DRMP3_VSUB(DRMP3_VMUL(vu, vc0), DRMP3_VMUL(vd, vc1))); + vd = DRMP3_VADD(DRMP3_VMUL(vu, vc1), DRMP3_VMUL(vd, vc0)); + DRMP3_VSTORE(grbuf + 14 - i, DRMP3_VREV(vd)); + } +#endif +#ifndef DR_MP3_ONLY_SIMD + for(; i < 8; i++) + { + float u = grbuf[18 + i]; + float d = grbuf[17 - i]; + grbuf[18 + i] = u*g_aa[0][i] - d*g_aa[1][i]; + grbuf[17 - i] = u*g_aa[1][i] + d*g_aa[0][i]; + } +#endif + } +} + +static void drmp3_L3_dct3_9(float *y) +{ + float s0, s1, s2, s3, s4, s5, s6, s7, s8, t0, t2, t4; + + s0 = y[0]; s2 = y[2]; s4 = y[4]; s6 = y[6]; s8 = y[8]; + t0 = s0 + s6*0.5f; + s0 -= s6; + t4 = (s4 + s2)*0.93969262f; + t2 = (s8 + s2)*0.76604444f; + s6 = (s4 - s8)*0.17364818f; + s4 += s8 - s2; + + s2 = s0 - s4*0.5f; + y[4] = s4 + s0; + s8 = t0 - t2 + s6; + s0 = t0 - t4 + t2; + s4 = t0 + t4 - s6; + + s1 = y[1]; s3 = y[3]; s5 = y[5]; s7 = y[7]; + + s3 *= 0.86602540f; + t0 = (s5 + s1)*0.98480775f; + t4 = (s5 - s7)*0.34202014f; + t2 = (s1 + s7)*0.64278761f; + s1 = (s1 - s5 - s7)*0.86602540f; + + s5 = t0 - s3 - t2; + s7 = t4 - s3 - t0; + s3 = t4 + s3 - t2; + + y[0] = s4 - s7; + y[1] = s2 + s1; + y[2] = s0 - s3; + y[3] = s8 + s5; + y[5] = s8 - s5; + y[6] = s0 + s3; + y[7] = s2 - s1; + y[8] = s4 + s7; +} + +static void drmp3_L3_imdct36(float *grbuf, float *overlap, const float *window, int nbands) +{ + int i, j; + static const float g_twid9[18] = { + 0.73727734f,0.79335334f,0.84339145f,0.88701083f,0.92387953f,0.95371695f,0.97629601f,0.99144486f,0.99904822f,0.67559021f,0.60876143f,0.53729961f,0.46174861f,0.38268343f,0.30070580f,0.21643961f,0.13052619f,0.04361938f + }; + + for (j = 0; j < nbands; j++, grbuf += 18, overlap += 9) + { + float co[9], si[9]; + co[0] = -grbuf[0]; + si[0] = grbuf[17]; + for (i = 0; i < 4; i++) + { + si[8 - 2*i] = grbuf[4*i + 1] - grbuf[4*i + 2]; + co[1 + 2*i] = grbuf[4*i + 1] + grbuf[4*i + 2]; + si[7 - 2*i] = grbuf[4*i + 4] - grbuf[4*i + 3]; + co[2 + 2*i] = -(grbuf[4*i + 3] + grbuf[4*i + 4]); + } + drmp3_L3_dct3_9(co); + drmp3_L3_dct3_9(si); + + si[1] = -si[1]; + si[3] = -si[3]; + si[5] = -si[5]; + si[7] = -si[7]; + + i = 0; + +#if DRMP3_HAVE_SIMD + if (drmp3_have_simd()) for (; i < 8; i += 4) + { + drmp3_f4 vovl = DRMP3_VLD(overlap + i); + drmp3_f4 vc = DRMP3_VLD(co + i); + drmp3_f4 vs = DRMP3_VLD(si + i); + drmp3_f4 vr0 = DRMP3_VLD(g_twid9 + i); + drmp3_f4 vr1 = DRMP3_VLD(g_twid9 + 9 + i); + drmp3_f4 vw0 = DRMP3_VLD(window + i); + drmp3_f4 vw1 = DRMP3_VLD(window + 9 + i); + drmp3_f4 vsum = DRMP3_VADD(DRMP3_VMUL(vc, vr1), DRMP3_VMUL(vs, vr0)); + DRMP3_VSTORE(overlap + i, DRMP3_VSUB(DRMP3_VMUL(vc, vr0), DRMP3_VMUL(vs, vr1))); + DRMP3_VSTORE(grbuf + i, DRMP3_VSUB(DRMP3_VMUL(vovl, vw0), DRMP3_VMUL(vsum, vw1))); + vsum = DRMP3_VADD(DRMP3_VMUL(vovl, vw1), DRMP3_VMUL(vsum, vw0)); + DRMP3_VSTORE(grbuf + 14 - i, DRMP3_VREV(vsum)); + } +#endif + for (; i < 9; i++) + { + float ovl = overlap[i]; + float sum = co[i]*g_twid9[9 + i] + si[i]*g_twid9[0 + i]; + overlap[i] = co[i]*g_twid9[0 + i] - si[i]*g_twid9[9 + i]; + grbuf[i] = ovl*window[0 + i] - sum*window[9 + i]; + grbuf[17 - i] = ovl*window[9 + i] + sum*window[0 + i]; + } + } +} + +static void drmp3_L3_idct3(float x0, float x1, float x2, float *dst) +{ + float m1 = x1*0.86602540f; + float a1 = x0 - x2*0.5f; + dst[1] = x0 + x2; + dst[0] = a1 + m1; + dst[2] = a1 - m1; +} + +static void drmp3_L3_imdct12(float *x, float *dst, float *overlap) +{ + static const float g_twid3[6] = { 0.79335334f,0.92387953f,0.99144486f, 0.60876143f,0.38268343f,0.13052619f }; + float co[3], si[3]; + int i; + + drmp3_L3_idct3(-x[0], x[6] + x[3], x[12] + x[9], co); + drmp3_L3_idct3(x[15], x[12] - x[9], x[6] - x[3], si); + si[1] = -si[1]; + + for (i = 0; i < 3; i++) + { + float ovl = overlap[i]; + float sum = co[i]*g_twid3[3 + i] + si[i]*g_twid3[0 + i]; + overlap[i] = co[i]*g_twid3[0 + i] - si[i]*g_twid3[3 + i]; + dst[i] = ovl*g_twid3[2 - i] - sum*g_twid3[5 - i]; + dst[5 - i] = ovl*g_twid3[5 - i] + sum*g_twid3[2 - i]; + } +} + +static void drmp3_L3_imdct_short(float *grbuf, float *overlap, int nbands) +{ + for (;nbands > 0; nbands--, overlap += 9, grbuf += 18) + { + float tmp[18]; + memcpy(tmp, grbuf, sizeof(tmp)); + memcpy(grbuf, overlap, 6*sizeof(float)); + drmp3_L3_imdct12(tmp, grbuf + 6, overlap + 6); + drmp3_L3_imdct12(tmp + 1, grbuf + 12, overlap + 6); + drmp3_L3_imdct12(tmp + 2, overlap, overlap + 6); + } +} + +static void drmp3_L3_change_sign(float *grbuf) +{ + int b, i; + for (b = 0, grbuf += 18; b < 32; b += 2, grbuf += 36) + for (i = 1; i < 18; i += 2) + grbuf[i] = -grbuf[i]; +} + +static void drmp3_L3_imdct_gr(float *grbuf, float *overlap, unsigned block_type, unsigned n_long_bands) +{ + static const float g_mdct_window[2][18] = { + { 0.99904822f,0.99144486f,0.97629601f,0.95371695f,0.92387953f,0.88701083f,0.84339145f,0.79335334f,0.73727734f,0.04361938f,0.13052619f,0.21643961f,0.30070580f,0.38268343f,0.46174861f,0.53729961f,0.60876143f,0.67559021f }, + { 1,1,1,1,1,1,0.99144486f,0.92387953f,0.79335334f,0,0,0,0,0,0,0.13052619f,0.38268343f,0.60876143f } + }; + if (n_long_bands) + { + drmp3_L3_imdct36(grbuf, overlap, g_mdct_window[0], n_long_bands); + grbuf += 18*n_long_bands; + overlap += 9*n_long_bands; + } + if (block_type == DRMP3_SHORT_BLOCK_TYPE) + drmp3_L3_imdct_short(grbuf, overlap, 32 - n_long_bands); + else + drmp3_L3_imdct36(grbuf, overlap, g_mdct_window[block_type == DRMP3_STOP_BLOCK_TYPE], 32 - n_long_bands); +} + +static void drmp3_L3_save_reservoir(drmp3dec *h, drmp3dec_scratch *s) +{ + int pos = (s->bs.pos + 7)/8u; + int remains = s->bs.limit/8u - pos; + if (remains > DRMP3_MAX_BITRESERVOIR_BYTES) + { + pos += remains - DRMP3_MAX_BITRESERVOIR_BYTES; + remains = DRMP3_MAX_BITRESERVOIR_BYTES; + } + if (remains > 0) + { + memmove(h->reserv_buf, s->maindata + pos, remains); + } + h->reserv = remains; +} + +static int drmp3_L3_restore_reservoir(drmp3dec *h, drmp3_bs *bs, drmp3dec_scratch *s, int main_data_begin) +{ + int frame_bytes = (bs->limit - bs->pos)/8; + int bytes_have = DRMP3_MIN(h->reserv, main_data_begin); + memcpy(s->maindata, h->reserv_buf + DRMP3_MAX(0, h->reserv - main_data_begin), DRMP3_MIN(h->reserv, main_data_begin)); + memcpy(s->maindata + bytes_have, bs->buf + bs->pos/8, frame_bytes); + drmp3_bs_init(&s->bs, s->maindata, bytes_have + frame_bytes); + return h->reserv >= main_data_begin; +} + +static void drmp3_L3_decode(drmp3dec *h, drmp3dec_scratch *s, drmp3_L3_gr_info *gr_info, int nch) +{ + int ch; + + for (ch = 0; ch < nch; ch++) + { + int layer3gr_limit = s->bs.pos + gr_info[ch].part_23_length; + drmp3_L3_decode_scalefactors(h->header, s->ist_pos[ch], &s->bs, gr_info + ch, s->scf, ch); + drmp3_L3_huffman(s->grbuf[ch], &s->bs, gr_info + ch, s->scf, layer3gr_limit); + } + + if (DRMP3_HDR_TEST_I_STEREO(h->header)) + { + drmp3_L3_intensity_stereo(s->grbuf[0], s->ist_pos[1], gr_info, h->header); + } else if (DRMP3_HDR_IS_MS_STEREO(h->header)) + { + drmp3_L3_midside_stereo(s->grbuf[0], 576); + } + + for (ch = 0; ch < nch; ch++, gr_info++) + { + int aa_bands = 31; + int n_long_bands = (gr_info->mixed_block_flag ? 2 : 0) << (int)(DRMP3_HDR_GET_MY_SAMPLE_RATE(h->header) == 2); + + if (gr_info->n_short_sfb) + { + aa_bands = n_long_bands - 1; + drmp3_L3_reorder(s->grbuf[ch] + n_long_bands*18, s->syn[0], gr_info->sfbtab + gr_info->n_long_sfb); + } + + drmp3_L3_antialias(s->grbuf[ch], aa_bands); + drmp3_L3_imdct_gr(s->grbuf[ch], h->mdct_overlap[ch], gr_info->block_type, n_long_bands); + drmp3_L3_change_sign(s->grbuf[ch]); + } +} + +static void drmp3d_DCT_II(float *grbuf, int n) +{ + static const float g_sec[24] = { + 10.19000816f,0.50060302f,0.50241929f,3.40760851f,0.50547093f,0.52249861f,2.05778098f,0.51544732f,0.56694406f,1.48416460f,0.53104258f,0.64682180f,1.16943991f,0.55310392f,0.78815460f,0.97256821f,0.58293498f,1.06067765f,0.83934963f,0.62250412f,1.72244716f,0.74453628f,0.67480832f,5.10114861f + }; + int i, k = 0; +#if DRMP3_HAVE_SIMD + if (drmp3_have_simd()) for (; k < n; k += 4) + { + drmp3_f4 t[4][8], *x; + float *y = grbuf + k; + + for (x = t[0], i = 0; i < 8; i++, x++) + { + drmp3_f4 x0 = DRMP3_VLD(&y[i*18]); + drmp3_f4 x1 = DRMP3_VLD(&y[(15 - i)*18]); + drmp3_f4 x2 = DRMP3_VLD(&y[(16 + i)*18]); + drmp3_f4 x3 = DRMP3_VLD(&y[(31 - i)*18]); + drmp3_f4 t0 = DRMP3_VADD(x0, x3); + drmp3_f4 t1 = DRMP3_VADD(x1, x2); + drmp3_f4 t2 = DRMP3_VMUL_S(DRMP3_VSUB(x1, x2), g_sec[3*i + 0]); + drmp3_f4 t3 = DRMP3_VMUL_S(DRMP3_VSUB(x0, x3), g_sec[3*i + 1]); + x[0] = DRMP3_VADD(t0, t1); + x[8] = DRMP3_VMUL_S(DRMP3_VSUB(t0, t1), g_sec[3*i + 2]); + x[16] = DRMP3_VADD(t3, t2); + x[24] = DRMP3_VMUL_S(DRMP3_VSUB(t3, t2), g_sec[3*i + 2]); + } + for (x = t[0], i = 0; i < 4; i++, x += 8) + { + drmp3_f4 x0 = x[0], x1 = x[1], x2 = x[2], x3 = x[3], x4 = x[4], x5 = x[5], x6 = x[6], x7 = x[7], xt; + xt = DRMP3_VSUB(x0, x7); x0 = DRMP3_VADD(x0, x7); + x7 = DRMP3_VSUB(x1, x6); x1 = DRMP3_VADD(x1, x6); + x6 = DRMP3_VSUB(x2, x5); x2 = DRMP3_VADD(x2, x5); + x5 = DRMP3_VSUB(x3, x4); x3 = DRMP3_VADD(x3, x4); + x4 = DRMP3_VSUB(x0, x3); x0 = DRMP3_VADD(x0, x3); + x3 = DRMP3_VSUB(x1, x2); x1 = DRMP3_VADD(x1, x2); + x[0] = DRMP3_VADD(x0, x1); + x[4] = DRMP3_VMUL_S(DRMP3_VSUB(x0, x1), 0.70710677f); + x5 = DRMP3_VADD(x5, x6); + x6 = DRMP3_VMUL_S(DRMP3_VADD(x6, x7), 0.70710677f); + x7 = DRMP3_VADD(x7, xt); + x3 = DRMP3_VMUL_S(DRMP3_VADD(x3, x4), 0.70710677f); + x5 = DRMP3_VSUB(x5, DRMP3_VMUL_S(x7, 0.198912367f)); /* rotate by PI/8 */ + x7 = DRMP3_VADD(x7, DRMP3_VMUL_S(x5, 0.382683432f)); + x5 = DRMP3_VSUB(x5, DRMP3_VMUL_S(x7, 0.198912367f)); + x0 = DRMP3_VSUB(xt, x6); xt = DRMP3_VADD(xt, x6); + x[1] = DRMP3_VMUL_S(DRMP3_VADD(xt, x7), 0.50979561f); + x[2] = DRMP3_VMUL_S(DRMP3_VADD(x4, x3), 0.54119611f); + x[3] = DRMP3_VMUL_S(DRMP3_VSUB(x0, x5), 0.60134488f); + x[5] = DRMP3_VMUL_S(DRMP3_VADD(x0, x5), 0.89997619f); + x[6] = DRMP3_VMUL_S(DRMP3_VSUB(x4, x3), 1.30656302f); + x[7] = DRMP3_VMUL_S(DRMP3_VSUB(xt, x7), 2.56291556f); + } + + if (k > n - 3) + { +#if DRMP3_HAVE_SSE +#define DRMP3_VSAVE2(i, v) _mm_storel_pi((__m64 *)(void*)&y[i*18], v) +#else +#define DRMP3_VSAVE2(i, v) vst1_f32((float32_t *)&y[i*18], vget_low_f32(v)) +#endif + for (i = 0; i < 7; i++, y += 4*18) + { + drmp3_f4 s = DRMP3_VADD(t[3][i], t[3][i + 1]); + DRMP3_VSAVE2(0, t[0][i]); + DRMP3_VSAVE2(1, DRMP3_VADD(t[2][i], s)); + DRMP3_VSAVE2(2, DRMP3_VADD(t[1][i], t[1][i + 1])); + DRMP3_VSAVE2(3, DRMP3_VADD(t[2][1 + i], s)); + } + DRMP3_VSAVE2(0, t[0][7]); + DRMP3_VSAVE2(1, DRMP3_VADD(t[2][7], t[3][7])); + DRMP3_VSAVE2(2, t[1][7]); + DRMP3_VSAVE2(3, t[3][7]); + } else + { +#define DRMP3_VSAVE4(i, v) DRMP3_VSTORE(&y[i*18], v) + for (i = 0; i < 7; i++, y += 4*18) + { + drmp3_f4 s = DRMP3_VADD(t[3][i], t[3][i + 1]); + DRMP3_VSAVE4(0, t[0][i]); + DRMP3_VSAVE4(1, DRMP3_VADD(t[2][i], s)); + DRMP3_VSAVE4(2, DRMP3_VADD(t[1][i], t[1][i + 1])); + DRMP3_VSAVE4(3, DRMP3_VADD(t[2][1 + i], s)); + } + DRMP3_VSAVE4(0, t[0][7]); + DRMP3_VSAVE4(1, DRMP3_VADD(t[2][7], t[3][7])); + DRMP3_VSAVE4(2, t[1][7]); + DRMP3_VSAVE4(3, t[3][7]); + } + } else +#endif +#ifdef DR_MP3_ONLY_SIMD + {} /* for HAVE_SIMD=1, MINIMP3_ONLY_SIMD=1 case we do not need non-intrinsic "else" branch */ +#else + for (; k < n; k++) + { + float t[4][8], *x, *y = grbuf + k; + + for (x = t[0], i = 0; i < 8; i++, x++) + { + float x0 = y[i*18]; + float x1 = y[(15 - i)*18]; + float x2 = y[(16 + i)*18]; + float x3 = y[(31 - i)*18]; + float t0 = x0 + x3; + float t1 = x1 + x2; + float t2 = (x1 - x2)*g_sec[3*i + 0]; + float t3 = (x0 - x3)*g_sec[3*i + 1]; + x[0] = t0 + t1; + x[8] = (t0 - t1)*g_sec[3*i + 2]; + x[16] = t3 + t2; + x[24] = (t3 - t2)*g_sec[3*i + 2]; + } + for (x = t[0], i = 0; i < 4; i++, x += 8) + { + float x0 = x[0], x1 = x[1], x2 = x[2], x3 = x[3], x4 = x[4], x5 = x[5], x6 = x[6], x7 = x[7], xt; + xt = x0 - x7; x0 += x7; + x7 = x1 - x6; x1 += x6; + x6 = x2 - x5; x2 += x5; + x5 = x3 - x4; x3 += x4; + x4 = x0 - x3; x0 += x3; + x3 = x1 - x2; x1 += x2; + x[0] = x0 + x1; + x[4] = (x0 - x1)*0.70710677f; + x5 = x5 + x6; + x6 = (x6 + x7)*0.70710677f; + x7 = x7 + xt; + x3 = (x3 + x4)*0.70710677f; + x5 -= x7*0.198912367f; /* rotate by PI/8 */ + x7 += x5*0.382683432f; + x5 -= x7*0.198912367f; + x0 = xt - x6; xt += x6; + x[1] = (xt + x7)*0.50979561f; + x[2] = (x4 + x3)*0.54119611f; + x[3] = (x0 - x5)*0.60134488f; + x[5] = (x0 + x5)*0.89997619f; + x[6] = (x4 - x3)*1.30656302f; + x[7] = (xt - x7)*2.56291556f; + + } + for (i = 0; i < 7; i++, y += 4*18) + { + y[0*18] = t[0][i]; + y[1*18] = t[2][i] + t[3][i] + t[3][i + 1]; + y[2*18] = t[1][i] + t[1][i + 1]; + y[3*18] = t[2][i + 1] + t[3][i] + t[3][i + 1]; + } + y[0*18] = t[0][7]; + y[1*18] = t[2][7] + t[3][7]; + y[2*18] = t[1][7]; + y[3*18] = t[3][7]; + } +#endif +} + +#ifndef DR_MP3_FLOAT_OUTPUT +typedef drmp3_int16 drmp3d_sample_t; + +static drmp3_int16 drmp3d_scale_pcm(float sample) +{ + drmp3_int16 s; +#if DRMP3_HAVE_ARMV6 + drmp3_int32 s32 = (drmp3_int32)(sample + .5f); + s32 -= (s32 < 0); + s = (drmp3_int16)drmp3_clip_int16_arm(s32); +#else + if (sample >= 32766.5) return (drmp3_int16) 32767; + if (sample <= -32767.5) return (drmp3_int16)-32768; + s = (drmp3_int16)(sample + .5f); + s -= (s < 0); /* away from zero, to be compliant */ +#endif + return s; +} +#else +typedef float drmp3d_sample_t; + +static float drmp3d_scale_pcm(float sample) +{ + return sample*(1.f/32768.f); +} +#endif + +static void drmp3d_synth_pair(drmp3d_sample_t *pcm, int nch, const float *z) +{ + float a; + a = (z[14*64] - z[ 0]) * 29; + a += (z[ 1*64] + z[13*64]) * 213; + a += (z[12*64] - z[ 2*64]) * 459; + a += (z[ 3*64] + z[11*64]) * 2037; + a += (z[10*64] - z[ 4*64]) * 5153; + a += (z[ 5*64] + z[ 9*64]) * 6574; + a += (z[ 8*64] - z[ 6*64]) * 37489; + a += z[ 7*64] * 75038; + pcm[0] = drmp3d_scale_pcm(a); + + z += 2; + a = z[14*64] * 104; + a += z[12*64] * 1567; + a += z[10*64] * 9727; + a += z[ 8*64] * 64019; + a += z[ 6*64] * -9975; + a += z[ 4*64] * -45; + a += z[ 2*64] * 146; + a += z[ 0*64] * -5; + pcm[16*nch] = drmp3d_scale_pcm(a); +} + +static void drmp3d_synth(float *xl, drmp3d_sample_t *dstl, int nch, float *lins) +{ + int i; + float *xr = xl + 576*(nch - 1); + drmp3d_sample_t *dstr = dstl + (nch - 1); + + static const float g_win[] = { + -1,26,-31,208,218,401,-519,2063,2000,4788,-5517,7134,5959,35640,-39336,74992, + -1,24,-35,202,222,347,-581,2080,1952,4425,-5879,7640,5288,33791,-41176,74856, + -1,21,-38,196,225,294,-645,2087,1893,4063,-6237,8092,4561,31947,-43006,74630, + -1,19,-41,190,227,244,-711,2085,1822,3705,-6589,8492,3776,30112,-44821,74313, + -1,17,-45,183,228,197,-779,2075,1739,3351,-6935,8840,2935,28289,-46617,73908, + -1,16,-49,176,228,153,-848,2057,1644,3004,-7271,9139,2037,26482,-48390,73415, + -2,14,-53,169,227,111,-919,2032,1535,2663,-7597,9389,1082,24694,-50137,72835, + -2,13,-58,161,224,72,-991,2001,1414,2330,-7910,9592,70,22929,-51853,72169, + -2,11,-63,154,221,36,-1064,1962,1280,2006,-8209,9750,-998,21189,-53534,71420, + -2,10,-68,147,215,2,-1137,1919,1131,1692,-8491,9863,-2122,19478,-55178,70590, + -3,9,-73,139,208,-29,-1210,1870,970,1388,-8755,9935,-3300,17799,-56778,69679, + -3,8,-79,132,200,-57,-1283,1817,794,1095,-8998,9966,-4533,16155,-58333,68692, + -4,7,-85,125,189,-83,-1356,1759,605,814,-9219,9959,-5818,14548,-59838,67629, + -4,7,-91,117,177,-106,-1428,1698,402,545,-9416,9916,-7154,12980,-61289,66494, + -5,6,-97,111,163,-127,-1498,1634,185,288,-9585,9838,-8540,11455,-62684,65290 + }; + float *zlin = lins + 15*64; + const float *w = g_win; + + zlin[4*15] = xl[18*16]; + zlin[4*15 + 1] = xr[18*16]; + zlin[4*15 + 2] = xl[0]; + zlin[4*15 + 3] = xr[0]; + + zlin[4*31] = xl[1 + 18*16]; + zlin[4*31 + 1] = xr[1 + 18*16]; + zlin[4*31 + 2] = xl[1]; + zlin[4*31 + 3] = xr[1]; + + drmp3d_synth_pair(dstr, nch, lins + 4*15 + 1); + drmp3d_synth_pair(dstr + 32*nch, nch, lins + 4*15 + 64 + 1); + drmp3d_synth_pair(dstl, nch, lins + 4*15); + drmp3d_synth_pair(dstl + 32*nch, nch, lins + 4*15 + 64); + +#if DRMP3_HAVE_SIMD + if (drmp3_have_simd()) for (i = 14; i >= 0; i--) + { +#define DRMP3_VLOAD(k) drmp3_f4 w0 = DRMP3_VSET(*w++); drmp3_f4 w1 = DRMP3_VSET(*w++); drmp3_f4 vz = DRMP3_VLD(&zlin[4*i - 64*k]); drmp3_f4 vy = DRMP3_VLD(&zlin[4*i - 64*(15 - k)]); +#define DRMP3_V0(k) { DRMP3_VLOAD(k) b = DRMP3_VADD(DRMP3_VMUL(vz, w1), DRMP3_VMUL(vy, w0)) ; a = DRMP3_VSUB(DRMP3_VMUL(vz, w0), DRMP3_VMUL(vy, w1)); } +#define DRMP3_V1(k) { DRMP3_VLOAD(k) b = DRMP3_VADD(b, DRMP3_VADD(DRMP3_VMUL(vz, w1), DRMP3_VMUL(vy, w0))); a = DRMP3_VADD(a, DRMP3_VSUB(DRMP3_VMUL(vz, w0), DRMP3_VMUL(vy, w1))); } +#define DRMP3_V2(k) { DRMP3_VLOAD(k) b = DRMP3_VADD(b, DRMP3_VADD(DRMP3_VMUL(vz, w1), DRMP3_VMUL(vy, w0))); a = DRMP3_VADD(a, DRMP3_VSUB(DRMP3_VMUL(vy, w1), DRMP3_VMUL(vz, w0))); } + drmp3_f4 a, b; + zlin[4*i] = xl[18*(31 - i)]; + zlin[4*i + 1] = xr[18*(31 - i)]; + zlin[4*i + 2] = xl[1 + 18*(31 - i)]; + zlin[4*i + 3] = xr[1 + 18*(31 - i)]; + zlin[4*i + 64] = xl[1 + 18*(1 + i)]; + zlin[4*i + 64 + 1] = xr[1 + 18*(1 + i)]; + zlin[4*i - 64 + 2] = xl[18*(1 + i)]; + zlin[4*i - 64 + 3] = xr[18*(1 + i)]; + + DRMP3_V0(0) DRMP3_V2(1) DRMP3_V1(2) DRMP3_V2(3) DRMP3_V1(4) DRMP3_V2(5) DRMP3_V1(6) DRMP3_V2(7) + + { +#ifndef DR_MP3_FLOAT_OUTPUT +#if DRMP3_HAVE_SSE + static const drmp3_f4 g_max = { 32767.0f, 32767.0f, 32767.0f, 32767.0f }; + static const drmp3_f4 g_min = { -32768.0f, -32768.0f, -32768.0f, -32768.0f }; + __m128i pcm8 = _mm_packs_epi32(_mm_cvtps_epi32(_mm_max_ps(_mm_min_ps(a, g_max), g_min)), + _mm_cvtps_epi32(_mm_max_ps(_mm_min_ps(b, g_max), g_min))); + dstr[(15 - i)*nch] = (drmp3_int16)_mm_extract_epi16(pcm8, 1); + dstr[(17 + i)*nch] = (drmp3_int16)_mm_extract_epi16(pcm8, 5); + dstl[(15 - i)*nch] = (drmp3_int16)_mm_extract_epi16(pcm8, 0); + dstl[(17 + i)*nch] = (drmp3_int16)_mm_extract_epi16(pcm8, 4); + dstr[(47 - i)*nch] = (drmp3_int16)_mm_extract_epi16(pcm8, 3); + dstr[(49 + i)*nch] = (drmp3_int16)_mm_extract_epi16(pcm8, 7); + dstl[(47 - i)*nch] = (drmp3_int16)_mm_extract_epi16(pcm8, 2); + dstl[(49 + i)*nch] = (drmp3_int16)_mm_extract_epi16(pcm8, 6); +#else + int16x4_t pcma, pcmb; + a = DRMP3_VADD(a, DRMP3_VSET(0.5f)); + b = DRMP3_VADD(b, DRMP3_VSET(0.5f)); + pcma = vqmovn_s32(vqaddq_s32(vcvtq_s32_f32(a), vreinterpretq_s32_u32(vcltq_f32(a, DRMP3_VSET(0))))); + pcmb = vqmovn_s32(vqaddq_s32(vcvtq_s32_f32(b), vreinterpretq_s32_u32(vcltq_f32(b, DRMP3_VSET(0))))); + vst1_lane_s16(dstr + (15 - i)*nch, pcma, 1); + vst1_lane_s16(dstr + (17 + i)*nch, pcmb, 1); + vst1_lane_s16(dstl + (15 - i)*nch, pcma, 0); + vst1_lane_s16(dstl + (17 + i)*nch, pcmb, 0); + vst1_lane_s16(dstr + (47 - i)*nch, pcma, 3); + vst1_lane_s16(dstr + (49 + i)*nch, pcmb, 3); + vst1_lane_s16(dstl + (47 - i)*nch, pcma, 2); + vst1_lane_s16(dstl + (49 + i)*nch, pcmb, 2); +#endif +#else + static const drmp3_f4 g_scale = { 1.0f/32768.0f, 1.0f/32768.0f, 1.0f/32768.0f, 1.0f/32768.0f }; + a = DRMP3_VMUL(a, g_scale); + b = DRMP3_VMUL(b, g_scale); +#if DRMP3_HAVE_SSE + _mm_store_ss(dstr + (15 - i)*nch, _mm_shuffle_ps(a, a, _MM_SHUFFLE(1, 1, 1, 1))); + _mm_store_ss(dstr + (17 + i)*nch, _mm_shuffle_ps(b, b, _MM_SHUFFLE(1, 1, 1, 1))); + _mm_store_ss(dstl + (15 - i)*nch, _mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 0, 0, 0))); + _mm_store_ss(dstl + (17 + i)*nch, _mm_shuffle_ps(b, b, _MM_SHUFFLE(0, 0, 0, 0))); + _mm_store_ss(dstr + (47 - i)*nch, _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 3, 3, 3))); + _mm_store_ss(dstr + (49 + i)*nch, _mm_shuffle_ps(b, b, _MM_SHUFFLE(3, 3, 3, 3))); + _mm_store_ss(dstl + (47 - i)*nch, _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 2, 2, 2))); + _mm_store_ss(dstl + (49 + i)*nch, _mm_shuffle_ps(b, b, _MM_SHUFFLE(2, 2, 2, 2))); +#else + vst1q_lane_f32(dstr + (15 - i)*nch, a, 1); + vst1q_lane_f32(dstr + (17 + i)*nch, b, 1); + vst1q_lane_f32(dstl + (15 - i)*nch, a, 0); + vst1q_lane_f32(dstl + (17 + i)*nch, b, 0); + vst1q_lane_f32(dstr + (47 - i)*nch, a, 3); + vst1q_lane_f32(dstr + (49 + i)*nch, b, 3); + vst1q_lane_f32(dstl + (47 - i)*nch, a, 2); + vst1q_lane_f32(dstl + (49 + i)*nch, b, 2); +#endif +#endif /* DR_MP3_FLOAT_OUTPUT */ + } + } else +#endif +#ifdef DR_MP3_ONLY_SIMD + {} /* for HAVE_SIMD=1, MINIMP3_ONLY_SIMD=1 case we do not need non-intrinsic "else" branch */ +#else + for (i = 14; i >= 0; i--) + { +#define DRMP3_LOAD(k) float w0 = *w++; float w1 = *w++; float *vz = &zlin[4*i - k*64]; float *vy = &zlin[4*i - (15 - k)*64]; +#define DRMP3_S0(k) { int j; DRMP3_LOAD(k); for (j = 0; j < 4; j++) b[j] = vz[j]*w1 + vy[j]*w0, a[j] = vz[j]*w0 - vy[j]*w1; } +#define DRMP3_S1(k) { int j; DRMP3_LOAD(k); for (j = 0; j < 4; j++) b[j] += vz[j]*w1 + vy[j]*w0, a[j] += vz[j]*w0 - vy[j]*w1; } +#define DRMP3_S2(k) { int j; DRMP3_LOAD(k); for (j = 0; j < 4; j++) b[j] += vz[j]*w1 + vy[j]*w0, a[j] += vy[j]*w1 - vz[j]*w0; } + float a[4], b[4]; + + zlin[4*i] = xl[18*(31 - i)]; + zlin[4*i + 1] = xr[18*(31 - i)]; + zlin[4*i + 2] = xl[1 + 18*(31 - i)]; + zlin[4*i + 3] = xr[1 + 18*(31 - i)]; + zlin[4*(i + 16)] = xl[1 + 18*(1 + i)]; + zlin[4*(i + 16) + 1] = xr[1 + 18*(1 + i)]; + zlin[4*(i - 16) + 2] = xl[18*(1 + i)]; + zlin[4*(i - 16) + 3] = xr[18*(1 + i)]; + + DRMP3_S0(0) DRMP3_S2(1) DRMP3_S1(2) DRMP3_S2(3) DRMP3_S1(4) DRMP3_S2(5) DRMP3_S1(6) DRMP3_S2(7) + + dstr[(15 - i)*nch] = drmp3d_scale_pcm(a[1]); + dstr[(17 + i)*nch] = drmp3d_scale_pcm(b[1]); + dstl[(15 - i)*nch] = drmp3d_scale_pcm(a[0]); + dstl[(17 + i)*nch] = drmp3d_scale_pcm(b[0]); + dstr[(47 - i)*nch] = drmp3d_scale_pcm(a[3]); + dstr[(49 + i)*nch] = drmp3d_scale_pcm(b[3]); + dstl[(47 - i)*nch] = drmp3d_scale_pcm(a[2]); + dstl[(49 + i)*nch] = drmp3d_scale_pcm(b[2]); + } +#endif +} + +static void drmp3d_synth_granule(float *qmf_state, float *grbuf, int nbands, int nch, drmp3d_sample_t *pcm, float *lins) +{ + int i; + for (i = 0; i < nch; i++) + { + drmp3d_DCT_II(grbuf + 576*i, nbands); + } + + memcpy(lins, qmf_state, sizeof(float)*15*64); + + for (i = 0; i < nbands; i += 2) + { + drmp3d_synth(grbuf + i, pcm + 32*nch*i, nch, lins + i*64); + } +#ifndef DR_MP3_NONSTANDARD_BUT_LOGICAL + if (nch == 1) + { + for (i = 0; i < 15*64; i += 2) + { + qmf_state[i] = lins[nbands*64 + i]; + } + } else +#endif + { + memcpy(qmf_state, lins + nbands*64, sizeof(float)*15*64); + } +} + +static int drmp3d_match_frame(const drmp3_uint8 *hdr, int mp3_bytes, int frame_bytes) +{ + int i, nmatch; + for (i = 0, nmatch = 0; nmatch < DRMP3_MAX_FRAME_SYNC_MATCHES; nmatch++) + { + i += drmp3_hdr_frame_bytes(hdr + i, frame_bytes) + drmp3_hdr_padding(hdr + i); + if (i + DRMP3_HDR_SIZE > mp3_bytes) + return nmatch > 0; + if (!drmp3_hdr_compare(hdr, hdr + i)) + return 0; + } + return 1; +} + +static int drmp3d_find_frame(const drmp3_uint8 *mp3, int mp3_bytes, int *free_format_bytes, int *ptr_frame_bytes) +{ + int i, k; + for (i = 0; i < mp3_bytes - DRMP3_HDR_SIZE; i++, mp3++) + { + if (drmp3_hdr_valid(mp3)) + { + int frame_bytes = drmp3_hdr_frame_bytes(mp3, *free_format_bytes); + int frame_and_padding = frame_bytes + drmp3_hdr_padding(mp3); + + for (k = DRMP3_HDR_SIZE; !frame_bytes && k < DRMP3_MAX_FREE_FORMAT_FRAME_SIZE && i + 2*k < mp3_bytes - DRMP3_HDR_SIZE; k++) + { + if (drmp3_hdr_compare(mp3, mp3 + k)) + { + int fb = k - drmp3_hdr_padding(mp3); + int nextfb = fb + drmp3_hdr_padding(mp3 + k); + if (i + k + nextfb + DRMP3_HDR_SIZE > mp3_bytes || !drmp3_hdr_compare(mp3, mp3 + k + nextfb)) + continue; + frame_and_padding = k; + frame_bytes = fb; + *free_format_bytes = fb; + } + } + + if ((frame_bytes && i + frame_and_padding <= mp3_bytes && + drmp3d_match_frame(mp3, mp3_bytes - i, frame_bytes)) || + (!i && frame_and_padding == mp3_bytes)) + { + *ptr_frame_bytes = frame_and_padding; + return i; + } + *free_format_bytes = 0; + } + } + *ptr_frame_bytes = 0; + return mp3_bytes; +} + +DRMP3_API void drmp3dec_init(drmp3dec *dec) +{ + dec->header[0] = 0; +} + +DRMP3_API int drmp3dec_decode_frame(drmp3dec *dec, const drmp3_uint8 *mp3, int mp3_bytes, void *pcm, drmp3dec_frame_info *info) +{ + int i = 0, igr, frame_size = 0, success = 1; + const drmp3_uint8 *hdr; + drmp3_bs bs_frame[1]; + drmp3dec_scratch scratch; + + if (mp3_bytes > 4 && dec->header[0] == 0xff && drmp3_hdr_compare(dec->header, mp3)) + { + frame_size = drmp3_hdr_frame_bytes(mp3, dec->free_format_bytes) + drmp3_hdr_padding(mp3); + if (frame_size != mp3_bytes && (frame_size + DRMP3_HDR_SIZE > mp3_bytes || !drmp3_hdr_compare(mp3, mp3 + frame_size))) + { + frame_size = 0; + } + } + if (!frame_size) + { + memset(dec, 0, sizeof(drmp3dec)); + i = drmp3d_find_frame(mp3, mp3_bytes, &dec->free_format_bytes, &frame_size); + if (!frame_size || i + frame_size > mp3_bytes) + { + info->frame_bytes = i; + return 0; + } + } + + hdr = mp3 + i; + memcpy(dec->header, hdr, DRMP3_HDR_SIZE); + info->frame_bytes = i + frame_size; + info->channels = DRMP3_HDR_IS_MONO(hdr) ? 1 : 2; + info->hz = drmp3_hdr_sample_rate_hz(hdr); + info->layer = 4 - DRMP3_HDR_GET_LAYER(hdr); + info->bitrate_kbps = drmp3_hdr_bitrate_kbps(hdr); + + drmp3_bs_init(bs_frame, hdr + DRMP3_HDR_SIZE, frame_size - DRMP3_HDR_SIZE); + if (DRMP3_HDR_IS_CRC(hdr)) + { + drmp3_bs_get_bits(bs_frame, 16); + } + + if (info->layer == 3) + { + int main_data_begin = drmp3_L3_read_side_info(bs_frame, scratch.gr_info, hdr); + if (main_data_begin < 0 || bs_frame->pos > bs_frame->limit) + { + drmp3dec_init(dec); + return 0; + } + success = drmp3_L3_restore_reservoir(dec, bs_frame, &scratch, main_data_begin); + if (success && pcm != NULL) + { + for (igr = 0; igr < (DRMP3_HDR_TEST_MPEG1(hdr) ? 2 : 1); igr++, pcm = DRMP3_OFFSET_PTR(pcm, sizeof(drmp3d_sample_t)*576*info->channels)) + { + memset(scratch.grbuf[0], 0, 576*2*sizeof(float)); + drmp3_L3_decode(dec, &scratch, scratch.gr_info + igr*info->channels, info->channels); + drmp3d_synth_granule(dec->qmf_state, scratch.grbuf[0], 18, info->channels, (drmp3d_sample_t*)pcm, scratch.syn[0]); + } + } + drmp3_L3_save_reservoir(dec, &scratch); + } else + { +#ifdef DR_MP3_ONLY_MP3 + return 0; +#else + drmp3_L12_scale_info sci[1]; + + if (pcm == NULL) { + return drmp3_hdr_frame_samples(hdr); + } + + drmp3_L12_read_scale_info(hdr, bs_frame, sci); + + memset(scratch.grbuf[0], 0, 576*2*sizeof(float)); + for (i = 0, igr = 0; igr < 3; igr++) + { + if (12 == (i += drmp3_L12_dequantize_granule(scratch.grbuf[0] + i, bs_frame, sci, info->layer | 1))) + { + i = 0; + drmp3_L12_apply_scf_384(sci, sci->scf + igr, scratch.grbuf[0]); + drmp3d_synth_granule(dec->qmf_state, scratch.grbuf[0], 12, info->channels, (drmp3d_sample_t*)pcm, scratch.syn[0]); + memset(scratch.grbuf[0], 0, 576*2*sizeof(float)); + pcm = DRMP3_OFFSET_PTR(pcm, sizeof(drmp3d_sample_t)*384*info->channels); + } + if (bs_frame->pos > bs_frame->limit) + { + drmp3dec_init(dec); + return 0; + } + } +#endif + } + + return success*drmp3_hdr_frame_samples(dec->header); +} + +DRMP3_API void drmp3dec_f32_to_s16(const float *in, drmp3_int16 *out, size_t num_samples) +{ + size_t i = 0; +#if DRMP3_HAVE_SIMD + size_t aligned_count = num_samples & ~7; + for(; i < aligned_count; i+=8) + { + drmp3_f4 scale = DRMP3_VSET(32768.0f); + drmp3_f4 a = DRMP3_VMUL(DRMP3_VLD(&in[i ]), scale); + drmp3_f4 b = DRMP3_VMUL(DRMP3_VLD(&in[i+4]), scale); +#if DRMP3_HAVE_SSE + drmp3_f4 s16max = DRMP3_VSET( 32767.0f); + drmp3_f4 s16min = DRMP3_VSET(-32768.0f); + __m128i pcm8 = _mm_packs_epi32(_mm_cvtps_epi32(_mm_max_ps(_mm_min_ps(a, s16max), s16min)), + _mm_cvtps_epi32(_mm_max_ps(_mm_min_ps(b, s16max), s16min))); + out[i ] = (drmp3_int16)_mm_extract_epi16(pcm8, 0); + out[i+1] = (drmp3_int16)_mm_extract_epi16(pcm8, 1); + out[i+2] = (drmp3_int16)_mm_extract_epi16(pcm8, 2); + out[i+3] = (drmp3_int16)_mm_extract_epi16(pcm8, 3); + out[i+4] = (drmp3_int16)_mm_extract_epi16(pcm8, 4); + out[i+5] = (drmp3_int16)_mm_extract_epi16(pcm8, 5); + out[i+6] = (drmp3_int16)_mm_extract_epi16(pcm8, 6); + out[i+7] = (drmp3_int16)_mm_extract_epi16(pcm8, 7); +#else + int16x4_t pcma, pcmb; + a = DRMP3_VADD(a, DRMP3_VSET(0.5f)); + b = DRMP3_VADD(b, DRMP3_VSET(0.5f)); + pcma = vqmovn_s32(vqaddq_s32(vcvtq_s32_f32(a), vreinterpretq_s32_u32(vcltq_f32(a, DRMP3_VSET(0))))); + pcmb = vqmovn_s32(vqaddq_s32(vcvtq_s32_f32(b), vreinterpretq_s32_u32(vcltq_f32(b, DRMP3_VSET(0))))); + vst1_lane_s16(out+i , pcma, 0); + vst1_lane_s16(out+i+1, pcma, 1); + vst1_lane_s16(out+i+2, pcma, 2); + vst1_lane_s16(out+i+3, pcma, 3); + vst1_lane_s16(out+i+4, pcmb, 0); + vst1_lane_s16(out+i+5, pcmb, 1); + vst1_lane_s16(out+i+6, pcmb, 2); + vst1_lane_s16(out+i+7, pcmb, 3); +#endif + } +#endif + for(; i < num_samples; i++) + { + float sample = in[i] * 32768.0f; + if (sample >= 32766.5) + out[i] = (drmp3_int16) 32767; + else if (sample <= -32767.5) + out[i] = (drmp3_int16)-32768; + else + { + short s = (drmp3_int16)(sample + .5f); + s -= (s < 0); /* away from zero, to be compliant */ + out[i] = s; + } + } +} + + + +/************************************************************************************************************************************************************ + + Main Public API + + ************************************************************************************************************************************************************/ +#include /* For sin() and exp(). */ + +#if defined(SIZE_MAX) + #define DRMP3_SIZE_MAX SIZE_MAX +#else + #if defined(_WIN64) || defined(_LP64) || defined(__LP64__) + #define DRMP3_SIZE_MAX ((drmp3_uint64)0xFFFFFFFFFFFFFFFF) + #else + #define DRMP3_SIZE_MAX 0xFFFFFFFF + #endif +#endif + +/* Options. */ +#ifndef DRMP3_SEEK_LEADING_MP3_FRAMES +#define DRMP3_SEEK_LEADING_MP3_FRAMES 2 +#endif + +#define DRMP3_MIN_DATA_CHUNK_SIZE 16384 + +/* The size in bytes of each chunk of data to read from the MP3 stream. minimp3 recommends at least 16K, but in an attempt to reduce data movement I'm making this slightly larger. */ +#ifndef DRMP3_DATA_CHUNK_SIZE +#define DRMP3_DATA_CHUNK_SIZE DRMP3_MIN_DATA_CHUNK_SIZE*4 +#endif + + +/* Standard library stuff. */ +#ifndef DRMP3_ASSERT +#include +#define DRMP3_ASSERT(expression) assert(expression) +#endif +#ifndef DRMP3_COPY_MEMORY +#define DRMP3_COPY_MEMORY(dst, src, sz) memcpy((dst), (src), (sz)) +#endif +#ifndef DRMP3_ZERO_MEMORY +#define DRMP3_ZERO_MEMORY(p, sz) memset((p), 0, (sz)) +#endif +#define DRMP3_ZERO_OBJECT(p) DRMP3_ZERO_MEMORY((p), sizeof(*(p))) +#ifndef DRMP3_MALLOC +#define DRMP3_MALLOC(sz) malloc((sz)) +#endif +#ifndef DRMP3_REALLOC +#define DRMP3_REALLOC(p, sz) realloc((p), (sz)) +#endif +#ifndef DRMP3_FREE +#define DRMP3_FREE(p) free((p)) +#endif + +#define DRMP3_COUNTOF(x) (sizeof(x) / sizeof(x[0])) +#define DRMP3_CLAMP(x, lo, hi) (DRMP3_MAX(lo, DRMP3_MIN(x, hi))) + +#ifndef DRMP3_PI_D +#define DRMP3_PI_D 3.14159265358979323846264 +#endif + +#define DRMP3_DEFAULT_RESAMPLER_LPF_ORDER 2 + +static DRMP3_INLINE float drmp3_mix_f32(float x, float y, float a) +{ + return x*(1-a) + y*a; +} +static DRMP3_INLINE float drmp3_mix_f32_fast(float x, float y, float a) +{ + float r0 = (y - x); + float r1 = r0*a; + return x + r1; + /*return x + (y - x)*a;*/ +} + + +/* +Greatest common factor using Euclid's algorithm iteratively. +*/ +static DRMP3_INLINE drmp3_uint32 drmp3_gcf_u32(drmp3_uint32 a, drmp3_uint32 b) +{ + for (;;) { + if (b == 0) { + break; + } else { + drmp3_uint32 t = a; + a = b; + b = t % a; + } + } + + return a; +} + + +static DRMP3_INLINE double drmp3_sin(double x) +{ + /* TODO: Implement custom sin(x). */ + return sin(x); +} + +static DRMP3_INLINE double drmp3_exp(double x) +{ + /* TODO: Implement custom exp(x). */ + return exp(x); +} + +static DRMP3_INLINE double drmp3_cos(double x) +{ + return drmp3_sin((DRMP3_PI_D*0.5) - x); +} + + +static void* drmp3__malloc_default(size_t sz, void* pUserData) +{ + (void)pUserData; + return DRMP3_MALLOC(sz); +} + +static void* drmp3__realloc_default(void* p, size_t sz, void* pUserData) +{ + (void)pUserData; + return DRMP3_REALLOC(p, sz); +} + +static void drmp3__free_default(void* p, void* pUserData) +{ + (void)pUserData; + DRMP3_FREE(p); +} + + +static void* drmp3__malloc_from_callbacks(size_t sz, const drmp3_allocation_callbacks* pAllocationCallbacks) +{ + if (pAllocationCallbacks == NULL) { + return NULL; + } + + if (pAllocationCallbacks->onMalloc != NULL) { + return pAllocationCallbacks->onMalloc(sz, pAllocationCallbacks->pUserData); + } + + /* Try using realloc(). */ + if (pAllocationCallbacks->onRealloc != NULL) { + return pAllocationCallbacks->onRealloc(NULL, sz, pAllocationCallbacks->pUserData); + } + + return NULL; +} + +static void* drmp3__realloc_from_callbacks(void* p, size_t szNew, size_t szOld, const drmp3_allocation_callbacks* pAllocationCallbacks) +{ + if (pAllocationCallbacks == NULL) { + return NULL; + } + + if (pAllocationCallbacks->onRealloc != NULL) { + return pAllocationCallbacks->onRealloc(p, szNew, pAllocationCallbacks->pUserData); + } + + /* Try emulating realloc() in terms of malloc()/free(). */ + if (pAllocationCallbacks->onMalloc != NULL && pAllocationCallbacks->onFree != NULL) { + void* p2; + + p2 = pAllocationCallbacks->onMalloc(szNew, pAllocationCallbacks->pUserData); + if (p2 == NULL) { + return NULL; + } + + if (p != NULL) { + DRMP3_COPY_MEMORY(p2, p, szOld); + pAllocationCallbacks->onFree(p, pAllocationCallbacks->pUserData); + } + + return p2; + } + + return NULL; +} + +static void drmp3__free_from_callbacks(void* p, const drmp3_allocation_callbacks* pAllocationCallbacks) +{ + if (p == NULL || pAllocationCallbacks == NULL) { + return; + } + + if (pAllocationCallbacks->onFree != NULL) { + pAllocationCallbacks->onFree(p, pAllocationCallbacks->pUserData); + } +} + + +static drmp3_allocation_callbacks drmp3_copy_allocation_callbacks_or_defaults(const drmp3_allocation_callbacks* pAllocationCallbacks) +{ + if (pAllocationCallbacks != NULL) { + /* Copy. */ + return *pAllocationCallbacks; + } else { + /* Defaults. */ + drmp3_allocation_callbacks allocationCallbacks; + allocationCallbacks.pUserData = NULL; + allocationCallbacks.onMalloc = drmp3__malloc_default; + allocationCallbacks.onRealloc = drmp3__realloc_default; + allocationCallbacks.onFree = drmp3__free_default; + return allocationCallbacks; + } +} + + + +static size_t drmp3__on_read(drmp3* pMP3, void* pBufferOut, size_t bytesToRead) +{ + size_t bytesRead = pMP3->onRead(pMP3->pUserData, pBufferOut, bytesToRead); + pMP3->streamCursor += bytesRead; + return bytesRead; +} + +static drmp3_bool32 drmp3__on_seek(drmp3* pMP3, int offset, drmp3_seek_origin origin) +{ + DRMP3_ASSERT(offset >= 0); + + if (!pMP3->onSeek(pMP3->pUserData, offset, origin)) { + return DRMP3_FALSE; + } + + if (origin == drmp3_seek_origin_start) { + pMP3->streamCursor = (drmp3_uint64)offset; + } else { + pMP3->streamCursor += offset; + } + + return DRMP3_TRUE; +} + +static drmp3_bool32 drmp3__on_seek_64(drmp3* pMP3, drmp3_uint64 offset, drmp3_seek_origin origin) +{ + if (offset <= 0x7FFFFFFF) { + return drmp3__on_seek(pMP3, (int)offset, origin); + } + + + /* Getting here "offset" is too large for a 32-bit integer. We just keep seeking forward until we hit the offset. */ + if (!drmp3__on_seek(pMP3, 0x7FFFFFFF, drmp3_seek_origin_start)) { + return DRMP3_FALSE; + } + + offset -= 0x7FFFFFFF; + while (offset > 0) { + if (offset <= 0x7FFFFFFF) { + if (!drmp3__on_seek(pMP3, (int)offset, drmp3_seek_origin_current)) { + return DRMP3_FALSE; + } + offset = 0; + } else { + if (!drmp3__on_seek(pMP3, 0x7FFFFFFF, drmp3_seek_origin_current)) { + return DRMP3_FALSE; + } + offset -= 0x7FFFFFFF; + } + } + + return DRMP3_TRUE; +} + + +static drmp3_uint32 drmp3_decode_next_frame_ex__callbacks(drmp3* pMP3, drmp3d_sample_t* pPCMFrames) +{ + drmp3_uint32 pcmFramesRead = 0; + + DRMP3_ASSERT(pMP3 != NULL); + DRMP3_ASSERT(pMP3->onRead != NULL); + + if (pMP3->atEnd) { + return 0; + } + + for (;;) { + drmp3dec_frame_info info; + + /* minimp3 recommends doing data submission in chunks of at least 16K. If we don't have at least 16K bytes available, get more. */ + if (pMP3->dataSize < DRMP3_MIN_DATA_CHUNK_SIZE) { + size_t bytesRead; + + /* First we need to move the data down. */ + if (pMP3->pData != NULL) { + memmove(pMP3->pData, pMP3->pData + pMP3->dataConsumed, pMP3->dataSize); + } + + pMP3->dataConsumed = 0; + + if (pMP3->dataCapacity < DRMP3_DATA_CHUNK_SIZE) { + drmp3_uint8* pNewData; + size_t newDataCap; + + newDataCap = DRMP3_DATA_CHUNK_SIZE; + + pNewData = (drmp3_uint8*)drmp3__realloc_from_callbacks(pMP3->pData, newDataCap, pMP3->dataCapacity, &pMP3->allocationCallbacks); + if (pNewData == NULL) { + return 0; /* Out of memory. */ + } + + pMP3->pData = pNewData; + pMP3->dataCapacity = newDataCap; + } + + bytesRead = drmp3__on_read(pMP3, pMP3->pData + pMP3->dataSize, (pMP3->dataCapacity - pMP3->dataSize)); + if (bytesRead == 0) { + if (pMP3->dataSize == 0) { + pMP3->atEnd = DRMP3_TRUE; + return 0; /* No data. */ + } + } + + pMP3->dataSize += bytesRead; + } + + if (pMP3->dataSize > INT_MAX) { + pMP3->atEnd = DRMP3_TRUE; + return 0; /* File too big. */ + } + + DRMP3_ASSERT(pMP3->pData != NULL); + DRMP3_ASSERT(pMP3->dataCapacity > 0); + + pcmFramesRead = drmp3dec_decode_frame(&pMP3->decoder, pMP3->pData + pMP3->dataConsumed, (int)pMP3->dataSize, pPCMFrames, &info); /* <-- Safe size_t -> int conversion thanks to the check above. */ + + /* Consume the data. */ + if (info.frame_bytes > 0) { + pMP3->dataConsumed += (size_t)info.frame_bytes; + pMP3->dataSize -= (size_t)info.frame_bytes; + } + + /* pcmFramesRead will be equal to 0 if decoding failed. If it is zero and info.frame_bytes > 0 then we have successfully decoded the frame. */ + if (pcmFramesRead > 0) { + pcmFramesRead = drmp3_hdr_frame_samples(pMP3->decoder.header); + pMP3->pcmFramesConsumedInMP3Frame = 0; + pMP3->pcmFramesRemainingInMP3Frame = pcmFramesRead; + pMP3->mp3FrameChannels = info.channels; + pMP3->mp3FrameSampleRate = info.hz; + break; + } else if (info.frame_bytes == 0) { + /* Need more data. minimp3 recommends doing data submission in 16K chunks. */ + size_t bytesRead; + + /* First we need to move the data down. */ + memmove(pMP3->pData, pMP3->pData + pMP3->dataConsumed, pMP3->dataSize); + pMP3->dataConsumed = 0; + + if (pMP3->dataCapacity == pMP3->dataSize) { + /* No room. Expand. */ + drmp3_uint8* pNewData; + size_t newDataCap; + + newDataCap = pMP3->dataCapacity + DRMP3_DATA_CHUNK_SIZE; + + pNewData = (drmp3_uint8*)drmp3__realloc_from_callbacks(pMP3->pData, newDataCap, pMP3->dataCapacity, &pMP3->allocationCallbacks); + if (pNewData == NULL) { + return 0; /* Out of memory. */ + } + + pMP3->pData = pNewData; + pMP3->dataCapacity = newDataCap; + } + + /* Fill in a chunk. */ + bytesRead = drmp3__on_read(pMP3, pMP3->pData + pMP3->dataSize, (pMP3->dataCapacity - pMP3->dataSize)); + if (bytesRead == 0) { + pMP3->atEnd = DRMP3_TRUE; + return 0; /* Error reading more data. */ + } + + pMP3->dataSize += bytesRead; + } + }; + + return pcmFramesRead; +} + +static drmp3_uint32 drmp3_decode_next_frame_ex__memory(drmp3* pMP3, drmp3d_sample_t* pPCMFrames) +{ + drmp3_uint32 pcmFramesRead = 0; + drmp3dec_frame_info info; + + DRMP3_ASSERT(pMP3 != NULL); + DRMP3_ASSERT(pMP3->memory.pData != NULL); + + if (pMP3->atEnd) { + return 0; + } + + pcmFramesRead = drmp3dec_decode_frame(&pMP3->decoder, pMP3->memory.pData + pMP3->memory.currentReadPos, (int)(pMP3->memory.dataSize - pMP3->memory.currentReadPos), pPCMFrames, &info); + if (pcmFramesRead > 0) { + pMP3->pcmFramesConsumedInMP3Frame = 0; + pMP3->pcmFramesRemainingInMP3Frame = pcmFramesRead; + pMP3->mp3FrameChannels = info.channels; + pMP3->mp3FrameSampleRate = info.hz; + } + + /* Consume the data. */ + pMP3->memory.currentReadPos += (size_t)info.frame_bytes; + + return pcmFramesRead; +} + +static drmp3_uint32 drmp3_decode_next_frame_ex(drmp3* pMP3, drmp3d_sample_t* pPCMFrames) +{ + if (pMP3->memory.pData != NULL && pMP3->memory.dataSize > 0) { + return drmp3_decode_next_frame_ex__memory(pMP3, pPCMFrames); + } else { + return drmp3_decode_next_frame_ex__callbacks(pMP3, pPCMFrames); + } +} + +static drmp3_uint32 drmp3_decode_next_frame(drmp3* pMP3) +{ + DRMP3_ASSERT(pMP3 != NULL); + return drmp3_decode_next_frame_ex(pMP3, (drmp3d_sample_t*)pMP3->pcmFrames); +} + +#if 0 +static drmp3_uint32 drmp3_seek_next_frame(drmp3* pMP3) +{ + drmp3_uint32 pcmFrameCount; + + DRMP3_ASSERT(pMP3 != NULL); + + pcmFrameCount = drmp3_decode_next_frame_ex(pMP3, NULL); + if (pcmFrameCount == 0) { + return 0; + } + + /* We have essentially just skipped past the frame, so just set the remaining samples to 0. */ + pMP3->currentPCMFrame += pcmFrameCount; + pMP3->pcmFramesConsumedInMP3Frame = pcmFrameCount; + pMP3->pcmFramesRemainingInMP3Frame = 0; + + return pcmFrameCount; +} +#endif + +static drmp3_bool32 drmp3_init_internal(drmp3* pMP3, drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, const drmp3_allocation_callbacks* pAllocationCallbacks) +{ + DRMP3_ASSERT(pMP3 != NULL); + DRMP3_ASSERT(onRead != NULL); + + /* This function assumes the output object has already been reset to 0. Do not do that here, otherwise things will break. */ + drmp3dec_init(&pMP3->decoder); + + pMP3->onRead = onRead; + pMP3->onSeek = onSeek; + pMP3->pUserData = pUserData; + pMP3->allocationCallbacks = drmp3_copy_allocation_callbacks_or_defaults(pAllocationCallbacks); + + if (pMP3->allocationCallbacks.onFree == NULL || (pMP3->allocationCallbacks.onMalloc == NULL && pMP3->allocationCallbacks.onRealloc == NULL)) { + return DRMP3_FALSE; /* Invalid allocation callbacks. */ + } + + /* Decode the first frame to confirm that it is indeed a valid MP3 stream. */ + if (!drmp3_decode_next_frame(pMP3)) { + drmp3__free_from_callbacks(pMP3->pData, &pMP3->allocationCallbacks); /* The call above may have allocated memory. Need to make sure it's freed before aborting. */ + return DRMP3_FALSE; /* Not a valid MP3 stream. */ + } + + pMP3->channels = pMP3->mp3FrameChannels; + pMP3->sampleRate = pMP3->mp3FrameSampleRate; + + return DRMP3_TRUE; +} + +DRMP3_API drmp3_bool32 drmp3_init(drmp3* pMP3, drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, const drmp3_allocation_callbacks* pAllocationCallbacks) +{ + if (pMP3 == NULL || onRead == NULL) { + return DRMP3_FALSE; + } + + DRMP3_ZERO_OBJECT(pMP3); + return drmp3_init_internal(pMP3, onRead, onSeek, pUserData, pAllocationCallbacks); +} + + +static size_t drmp3__on_read_memory(void* pUserData, void* pBufferOut, size_t bytesToRead) +{ + drmp3* pMP3 = (drmp3*)pUserData; + size_t bytesRemaining; + + DRMP3_ASSERT(pMP3 != NULL); + DRMP3_ASSERT(pMP3->memory.dataSize >= pMP3->memory.currentReadPos); + + bytesRemaining = pMP3->memory.dataSize - pMP3->memory.currentReadPos; + if (bytesToRead > bytesRemaining) { + bytesToRead = bytesRemaining; + } + + if (bytesToRead > 0) { + DRMP3_COPY_MEMORY(pBufferOut, pMP3->memory.pData + pMP3->memory.currentReadPos, bytesToRead); + pMP3->memory.currentReadPos += bytesToRead; + } + + return bytesToRead; +} + +static drmp3_bool32 drmp3__on_seek_memory(void* pUserData, int byteOffset, drmp3_seek_origin origin) +{ + drmp3* pMP3 = (drmp3*)pUserData; + + DRMP3_ASSERT(pMP3 != NULL); + + if (origin == drmp3_seek_origin_current) { + if (byteOffset > 0) { + if (pMP3->memory.currentReadPos + byteOffset > pMP3->memory.dataSize) { + byteOffset = (int)(pMP3->memory.dataSize - pMP3->memory.currentReadPos); /* Trying to seek too far forward. */ + } + } else { + if (pMP3->memory.currentReadPos < (size_t)-byteOffset) { + byteOffset = -(int)pMP3->memory.currentReadPos; /* Trying to seek too far backwards. */ + } + } + + /* This will never underflow thanks to the clamps above. */ + pMP3->memory.currentReadPos += byteOffset; + } else { + if ((drmp3_uint32)byteOffset <= pMP3->memory.dataSize) { + pMP3->memory.currentReadPos = byteOffset; + } else { + pMP3->memory.currentReadPos = pMP3->memory.dataSize; /* Trying to seek too far forward. */ + } + } + + return DRMP3_TRUE; +} + +DRMP3_API drmp3_bool32 drmp3_init_memory(drmp3* pMP3, const void* pData, size_t dataSize, const drmp3_allocation_callbacks* pAllocationCallbacks) +{ + if (pMP3 == NULL) { + return DRMP3_FALSE; + } + + DRMP3_ZERO_OBJECT(pMP3); + + if (pData == NULL || dataSize == 0) { + return DRMP3_FALSE; + } + + pMP3->memory.pData = (const drmp3_uint8*)pData; + pMP3->memory.dataSize = dataSize; + pMP3->memory.currentReadPos = 0; + + return drmp3_init_internal(pMP3, drmp3__on_read_memory, drmp3__on_seek_memory, pMP3, pAllocationCallbacks); +} + + +#ifndef DR_MP3_NO_STDIO +#include +#include /* For wcslen(), wcsrtombs() */ + +/* drmp3_result_from_errno() is only used inside DR_MP3_NO_STDIO for now. Move this out if it's ever used elsewhere. */ +#include +static drmp3_result drmp3_result_from_errno(int e) +{ + switch (e) + { + case 0: return DRMP3_SUCCESS; + #ifdef EPERM + case EPERM: return DRMP3_INVALID_OPERATION; + #endif + #ifdef ENOENT + case ENOENT: return DRMP3_DOES_NOT_EXIST; + #endif + #ifdef ESRCH + case ESRCH: return DRMP3_DOES_NOT_EXIST; + #endif + #ifdef EINTR + case EINTR: return DRMP3_INTERRUPT; + #endif + #ifdef EIO + case EIO: return DRMP3_IO_ERROR; + #endif + #ifdef ENXIO + case ENXIO: return DRMP3_DOES_NOT_EXIST; + #endif + #ifdef E2BIG + case E2BIG: return DRMP3_INVALID_ARGS; + #endif + #ifdef ENOEXEC + case ENOEXEC: return DRMP3_INVALID_FILE; + #endif + #ifdef EBADF + case EBADF: return DRMP3_INVALID_FILE; + #endif + #ifdef ECHILD + case ECHILD: return DRMP3_ERROR; + #endif + #ifdef EAGAIN + case EAGAIN: return DRMP3_UNAVAILABLE; + #endif + #ifdef ENOMEM + case ENOMEM: return DRMP3_OUT_OF_MEMORY; + #endif + #ifdef EACCES + case EACCES: return DRMP3_ACCESS_DENIED; + #endif + #ifdef EFAULT + case EFAULT: return DRMP3_BAD_ADDRESS; + #endif + #ifdef ENOTBLK + case ENOTBLK: return DRMP3_ERROR; + #endif + #ifdef EBUSY + case EBUSY: return DRMP3_BUSY; + #endif + #ifdef EEXIST + case EEXIST: return DRMP3_ALREADY_EXISTS; + #endif + #ifdef EXDEV + case EXDEV: return DRMP3_ERROR; + #endif + #ifdef ENODEV + case ENODEV: return DRMP3_DOES_NOT_EXIST; + #endif + #ifdef ENOTDIR + case ENOTDIR: return DRMP3_NOT_DIRECTORY; + #endif + #ifdef EISDIR + case EISDIR: return DRMP3_IS_DIRECTORY; + #endif + #ifdef EINVAL + case EINVAL: return DRMP3_INVALID_ARGS; + #endif + #ifdef ENFILE + case ENFILE: return DRMP3_TOO_MANY_OPEN_FILES; + #endif + #ifdef EMFILE + case EMFILE: return DRMP3_TOO_MANY_OPEN_FILES; + #endif + #ifdef ENOTTY + case ENOTTY: return DRMP3_INVALID_OPERATION; + #endif + #ifdef ETXTBSY + case ETXTBSY: return DRMP3_BUSY; + #endif + #ifdef EFBIG + case EFBIG: return DRMP3_TOO_BIG; + #endif + #ifdef ENOSPC + case ENOSPC: return DRMP3_NO_SPACE; + #endif + #ifdef ESPIPE + case ESPIPE: return DRMP3_BAD_SEEK; + #endif + #ifdef EROFS + case EROFS: return DRMP3_ACCESS_DENIED; + #endif + #ifdef EMLINK + case EMLINK: return DRMP3_TOO_MANY_LINKS; + #endif + #ifdef EPIPE + case EPIPE: return DRMP3_BAD_PIPE; + #endif + #ifdef EDOM + case EDOM: return DRMP3_OUT_OF_RANGE; + #endif + #ifdef ERANGE + case ERANGE: return DRMP3_OUT_OF_RANGE; + #endif + #ifdef EDEADLK + case EDEADLK: return DRMP3_DEADLOCK; + #endif + #ifdef ENAMETOOLONG + case ENAMETOOLONG: return DRMP3_PATH_TOO_LONG; + #endif + #ifdef ENOLCK + case ENOLCK: return DRMP3_ERROR; + #endif + #ifdef ENOSYS + case ENOSYS: return DRMP3_NOT_IMPLEMENTED; + #endif + #ifdef ENOTEMPTY + case ENOTEMPTY: return DRMP3_DIRECTORY_NOT_EMPTY; + #endif + #ifdef ELOOP + case ELOOP: return DRMP3_TOO_MANY_LINKS; + #endif + #ifdef ENOMSG + case ENOMSG: return DRMP3_NO_MESSAGE; + #endif + #ifdef EIDRM + case EIDRM: return DRMP3_ERROR; + #endif + #ifdef ECHRNG + case ECHRNG: return DRMP3_ERROR; + #endif + #ifdef EL2NSYNC + case EL2NSYNC: return DRMP3_ERROR; + #endif + #ifdef EL3HLT + case EL3HLT: return DRMP3_ERROR; + #endif + #ifdef EL3RST + case EL3RST: return DRMP3_ERROR; + #endif + #ifdef ELNRNG + case ELNRNG: return DRMP3_OUT_OF_RANGE; + #endif + #ifdef EUNATCH + case EUNATCH: return DRMP3_ERROR; + #endif + #ifdef ENOCSI + case ENOCSI: return DRMP3_ERROR; + #endif + #ifdef EL2HLT + case EL2HLT: return DRMP3_ERROR; + #endif + #ifdef EBADE + case EBADE: return DRMP3_ERROR; + #endif + #ifdef EBADR + case EBADR: return DRMP3_ERROR; + #endif + #ifdef EXFULL + case EXFULL: return DRMP3_ERROR; + #endif + #ifdef ENOANO + case ENOANO: return DRMP3_ERROR; + #endif + #ifdef EBADRQC + case EBADRQC: return DRMP3_ERROR; + #endif + #ifdef EBADSLT + case EBADSLT: return DRMP3_ERROR; + #endif + #ifdef EBFONT + case EBFONT: return DRMP3_INVALID_FILE; + #endif + #ifdef ENOSTR + case ENOSTR: return DRMP3_ERROR; + #endif + #ifdef ENODATA + case ENODATA: return DRMP3_NO_DATA_AVAILABLE; + #endif + #ifdef ETIME + case ETIME: return DRMP3_TIMEOUT; + #endif + #ifdef ENOSR + case ENOSR: return DRMP3_NO_DATA_AVAILABLE; + #endif + #ifdef ENONET + case ENONET: return DRMP3_NO_NETWORK; + #endif + #ifdef ENOPKG + case ENOPKG: return DRMP3_ERROR; + #endif + #ifdef EREMOTE + case EREMOTE: return DRMP3_ERROR; + #endif + #ifdef ENOLINK + case ENOLINK: return DRMP3_ERROR; + #endif + #ifdef EADV + case EADV: return DRMP3_ERROR; + #endif + #ifdef ESRMNT + case ESRMNT: return DRMP3_ERROR; + #endif + #ifdef ECOMM + case ECOMM: return DRMP3_ERROR; + #endif + #ifdef EPROTO + case EPROTO: return DRMP3_ERROR; + #endif + #ifdef EMULTIHOP + case EMULTIHOP: return DRMP3_ERROR; + #endif + #ifdef EDOTDOT + case EDOTDOT: return DRMP3_ERROR; + #endif + #ifdef EBADMSG + case EBADMSG: return DRMP3_BAD_MESSAGE; + #endif + #ifdef EOVERFLOW + case EOVERFLOW: return DRMP3_TOO_BIG; + #endif + #ifdef ENOTUNIQ + case ENOTUNIQ: return DRMP3_NOT_UNIQUE; + #endif + #ifdef EBADFD + case EBADFD: return DRMP3_ERROR; + #endif + #ifdef EREMCHG + case EREMCHG: return DRMP3_ERROR; + #endif + #ifdef ELIBACC + case ELIBACC: return DRMP3_ACCESS_DENIED; + #endif + #ifdef ELIBBAD + case ELIBBAD: return DRMP3_INVALID_FILE; + #endif + #ifdef ELIBSCN + case ELIBSCN: return DRMP3_INVALID_FILE; + #endif + #ifdef ELIBMAX + case ELIBMAX: return DRMP3_ERROR; + #endif + #ifdef ELIBEXEC + case ELIBEXEC: return DRMP3_ERROR; + #endif + #ifdef EILSEQ + case EILSEQ: return DRMP3_INVALID_DATA; + #endif + #ifdef ERESTART + case ERESTART: return DRMP3_ERROR; + #endif + #ifdef ESTRPIPE + case ESTRPIPE: return DRMP3_ERROR; + #endif + #ifdef EUSERS + case EUSERS: return DRMP3_ERROR; + #endif + #ifdef ENOTSOCK + case ENOTSOCK: return DRMP3_NOT_SOCKET; + #endif + #ifdef EDESTADDRREQ + case EDESTADDRREQ: return DRMP3_NO_ADDRESS; + #endif + #ifdef EMSGSIZE + case EMSGSIZE: return DRMP3_TOO_BIG; + #endif + #ifdef EPROTOTYPE + case EPROTOTYPE: return DRMP3_BAD_PROTOCOL; + #endif + #ifdef ENOPROTOOPT + case ENOPROTOOPT: return DRMP3_PROTOCOL_UNAVAILABLE; + #endif + #ifdef EPROTONOSUPPORT + case EPROTONOSUPPORT: return DRMP3_PROTOCOL_NOT_SUPPORTED; + #endif + #ifdef ESOCKTNOSUPPORT + case ESOCKTNOSUPPORT: return DRMP3_SOCKET_NOT_SUPPORTED; + #endif + #ifdef EOPNOTSUPP + case EOPNOTSUPP: return DRMP3_INVALID_OPERATION; + #endif + #ifdef EPFNOSUPPORT + case EPFNOSUPPORT: return DRMP3_PROTOCOL_FAMILY_NOT_SUPPORTED; + #endif + #ifdef EAFNOSUPPORT + case EAFNOSUPPORT: return DRMP3_ADDRESS_FAMILY_NOT_SUPPORTED; + #endif + #ifdef EADDRINUSE + case EADDRINUSE: return DRMP3_ALREADY_IN_USE; + #endif + #ifdef EADDRNOTAVAIL + case EADDRNOTAVAIL: return DRMP3_ERROR; + #endif + #ifdef ENETDOWN + case ENETDOWN: return DRMP3_NO_NETWORK; + #endif + #ifdef ENETUNREACH + case ENETUNREACH: return DRMP3_NO_NETWORK; + #endif + #ifdef ENETRESET + case ENETRESET: return DRMP3_NO_NETWORK; + #endif + #ifdef ECONNABORTED + case ECONNABORTED: return DRMP3_NO_NETWORK; + #endif + #ifdef ECONNRESET + case ECONNRESET: return DRMP3_CONNECTION_RESET; + #endif + #ifdef ENOBUFS + case ENOBUFS: return DRMP3_NO_SPACE; + #endif + #ifdef EISCONN + case EISCONN: return DRMP3_ALREADY_CONNECTED; + #endif + #ifdef ENOTCONN + case ENOTCONN: return DRMP3_NOT_CONNECTED; + #endif + #ifdef ESHUTDOWN + case ESHUTDOWN: return DRMP3_ERROR; + #endif + #ifdef ETOOMANYREFS + case ETOOMANYREFS: return DRMP3_ERROR; + #endif + #ifdef ETIMEDOUT + case ETIMEDOUT: return DRMP3_TIMEOUT; + #endif + #ifdef ECONNREFUSED + case ECONNREFUSED: return DRMP3_CONNECTION_REFUSED; + #endif + #ifdef EHOSTDOWN + case EHOSTDOWN: return DRMP3_NO_HOST; + #endif + #ifdef EHOSTUNREACH + case EHOSTUNREACH: return DRMP3_NO_HOST; + #endif + #ifdef EALREADY + case EALREADY: return DRMP3_IN_PROGRESS; + #endif + #ifdef EINPROGRESS + case EINPROGRESS: return DRMP3_IN_PROGRESS; + #endif + #ifdef ESTALE + case ESTALE: return DRMP3_INVALID_FILE; + #endif + #ifdef EUCLEAN + case EUCLEAN: return DRMP3_ERROR; + #endif + #ifdef ENOTNAM + case ENOTNAM: return DRMP3_ERROR; + #endif + #ifdef ENAVAIL + case ENAVAIL: return DRMP3_ERROR; + #endif + #ifdef EISNAM + case EISNAM: return DRMP3_ERROR; + #endif + #ifdef EREMOTEIO + case EREMOTEIO: return DRMP3_IO_ERROR; + #endif + #ifdef EDQUOT + case EDQUOT: return DRMP3_NO_SPACE; + #endif + #ifdef ENOMEDIUM + case ENOMEDIUM: return DRMP3_DOES_NOT_EXIST; + #endif + #ifdef EMEDIUMTYPE + case EMEDIUMTYPE: return DRMP3_ERROR; + #endif + #ifdef ECANCELED + case ECANCELED: return DRMP3_CANCELLED; + #endif + #ifdef ENOKEY + case ENOKEY: return DRMP3_ERROR; + #endif + #ifdef EKEYEXPIRED + case EKEYEXPIRED: return DRMP3_ERROR; + #endif + #ifdef EKEYREVOKED + case EKEYREVOKED: return DRMP3_ERROR; + #endif + #ifdef EKEYREJECTED + case EKEYREJECTED: return DRMP3_ERROR; + #endif + #ifdef EOWNERDEAD + case EOWNERDEAD: return DRMP3_ERROR; + #endif + #ifdef ENOTRECOVERABLE + case ENOTRECOVERABLE: return DRMP3_ERROR; + #endif + #ifdef ERFKILL + case ERFKILL: return DRMP3_ERROR; + #endif + #ifdef EHWPOISON + case EHWPOISON: return DRMP3_ERROR; + #endif + default: return DRMP3_ERROR; + } +} + +static drmp3_result drmp3_fopen(FILE** ppFile, const char* pFilePath, const char* pOpenMode) +{ +#if defined(_MSC_VER) && _MSC_VER >= 1400 + errno_t err; +#endif + + if (ppFile != NULL) { + *ppFile = NULL; /* Safety. */ + } + + if (pFilePath == NULL || pOpenMode == NULL || ppFile == NULL) { + return DRMP3_INVALID_ARGS; + } + +#if defined(_MSC_VER) && _MSC_VER >= 1400 + err = fopen_s(ppFile, pFilePath, pOpenMode); + if (err != 0) { + return drmp3_result_from_errno(err); + } +#else +#if defined(_WIN32) || defined(__APPLE__) + *ppFile = fopen(pFilePath, pOpenMode); +#else + #if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS == 64 && defined(_LARGEFILE64_SOURCE) + *ppFile = fopen64(pFilePath, pOpenMode); + #else + *ppFile = fopen(pFilePath, pOpenMode); + #endif +#endif + if (*ppFile == NULL) { + drmp3_result result = drmp3_result_from_errno(errno); + if (result == DRMP3_SUCCESS) { + result = DRMP3_ERROR; /* Just a safety check to make sure we never ever return success when pFile == NULL. */ + } + + return result; + } +#endif + + return DRMP3_SUCCESS; +} + +/* +_wfopen() isn't always available in all compilation environments. + + * Windows only. + * MSVC seems to support it universally as far back as VC6 from what I can tell (haven't checked further back). + * MinGW-64 (both 32- and 64-bit) seems to support it. + * MinGW wraps it in !defined(__STRICT_ANSI__). + * OpenWatcom wraps it in !defined(_NO_EXT_KEYS). + +This can be reviewed as compatibility issues arise. The preference is to use _wfopen_s() and _wfopen() as opposed to the wcsrtombs() +fallback, so if you notice your compiler not detecting this properly I'm happy to look at adding support. +*/ +#if defined(_WIN32) + #if defined(_MSC_VER) || defined(__MINGW64__) || (!defined(__STRICT_ANSI__) && !defined(_NO_EXT_KEYS)) + #define DRMP3_HAS_WFOPEN + #endif +#endif + +static drmp3_result drmp3_wfopen(FILE** ppFile, const wchar_t* pFilePath, const wchar_t* pOpenMode, const drmp3_allocation_callbacks* pAllocationCallbacks) +{ + if (ppFile != NULL) { + *ppFile = NULL; /* Safety. */ + } + + if (pFilePath == NULL || pOpenMode == NULL || ppFile == NULL) { + return DRMP3_INVALID_ARGS; + } + +#if defined(DRMP3_HAS_WFOPEN) + { + /* Use _wfopen() on Windows. */ + #if defined(_MSC_VER) && _MSC_VER >= 1400 + errno_t err = _wfopen_s(ppFile, pFilePath, pOpenMode); + if (err != 0) { + return drmp3_result_from_errno(err); + } + #else + *ppFile = _wfopen(pFilePath, pOpenMode); + if (*ppFile == NULL) { + return drmp3_result_from_errno(errno); + } + #endif + (void)pAllocationCallbacks; + } +#else + /* + Use fopen() on anything other than Windows. Requires a conversion. This is annoying because fopen() is locale specific. The only real way I can + think of to do this is with wcsrtombs(). Note that wcstombs() is apparently not thread-safe because it uses a static global mbstate_t object for + maintaining state. I've checked this with -std=c89 and it works, but if somebody get's a compiler error I'll look into improving compatibility. + */ + { + mbstate_t mbs; + size_t lenMB; + const wchar_t* pFilePathTemp = pFilePath; + char* pFilePathMB = NULL; + char pOpenModeMB[32] = {0}; + + /* Get the length first. */ + DRMP3_ZERO_OBJECT(&mbs); + lenMB = wcsrtombs(NULL, &pFilePathTemp, 0, &mbs); + if (lenMB == (size_t)-1) { + return drmp3_result_from_errno(errno); + } + + pFilePathMB = (char*)drmp3__malloc_from_callbacks(lenMB + 1, pAllocationCallbacks); + if (pFilePathMB == NULL) { + return DRMP3_OUT_OF_MEMORY; + } + + pFilePathTemp = pFilePath; + DRMP3_ZERO_OBJECT(&mbs); + wcsrtombs(pFilePathMB, &pFilePathTemp, lenMB + 1, &mbs); + + /* The open mode should always consist of ASCII characters so we should be able to do a trivial conversion. */ + { + size_t i = 0; + for (;;) { + if (pOpenMode[i] == 0) { + pOpenModeMB[i] = '\0'; + break; + } + + pOpenModeMB[i] = (char)pOpenMode[i]; + i += 1; + } + } + + *ppFile = fopen(pFilePathMB, pOpenModeMB); + + drmp3__free_from_callbacks(pFilePathMB, pAllocationCallbacks); + } + + if (*ppFile == NULL) { + return DRMP3_ERROR; + } +#endif + + return DRMP3_SUCCESS; +} + + + +static size_t drmp3__on_read_stdio(void* pUserData, void* pBufferOut, size_t bytesToRead) +{ + return fread(pBufferOut, 1, bytesToRead, (FILE*)pUserData); +} + +static drmp3_bool32 drmp3__on_seek_stdio(void* pUserData, int offset, drmp3_seek_origin origin) +{ + return fseek((FILE*)pUserData, offset, (origin == drmp3_seek_origin_current) ? SEEK_CUR : SEEK_SET) == 0; +} + +DRMP3_API drmp3_bool32 drmp3_init_file(drmp3* pMP3, const char* pFilePath, const drmp3_allocation_callbacks* pAllocationCallbacks) +{ + drmp3_bool32 result; + FILE* pFile; + + if (drmp3_fopen(&pFile, pFilePath, "rb") != DRMP3_SUCCESS) { + return DRMP3_FALSE; + } + + result = drmp3_init(pMP3, drmp3__on_read_stdio, drmp3__on_seek_stdio, (void*)pFile, pAllocationCallbacks); + if (result != DRMP3_TRUE) { + fclose(pFile); + return result; + } + + return DRMP3_TRUE; +} + +DRMP3_API drmp3_bool32 drmp3_init_file_w(drmp3* pMP3, const wchar_t* pFilePath, const drmp3_allocation_callbacks* pAllocationCallbacks) +{ + drmp3_bool32 result; + FILE* pFile; + + if (drmp3_wfopen(&pFile, pFilePath, L"rb", pAllocationCallbacks) != DRMP3_SUCCESS) { + return DRMP3_FALSE; + } + + result = drmp3_init(pMP3, drmp3__on_read_stdio, drmp3__on_seek_stdio, (void*)pFile, pAllocationCallbacks); + if (result != DRMP3_TRUE) { + fclose(pFile); + return result; + } + + return DRMP3_TRUE; +} +#endif + +DRMP3_API void drmp3_uninit(drmp3* pMP3) +{ + if (pMP3 == NULL) { + return; + } + +#ifndef DR_MP3_NO_STDIO + if (pMP3->onRead == drmp3__on_read_stdio) { + FILE* pFile = (FILE*)pMP3->pUserData; + if (pFile != NULL) { + fclose(pFile); + pMP3->pUserData = NULL; /* Make sure the file handle is cleared to NULL to we don't attempt to close it a second time. */ + } + } +#endif + + drmp3__free_from_callbacks(pMP3->pData, &pMP3->allocationCallbacks); +} + +#if defined(DR_MP3_FLOAT_OUTPUT) +static void drmp3_f32_to_s16(drmp3_int16* dst, const float* src, drmp3_uint64 sampleCount) +{ + drmp3_uint64 i; + drmp3_uint64 i4; + drmp3_uint64 sampleCount4; + + /* Unrolled. */ + i = 0; + sampleCount4 = sampleCount >> 2; + for (i4 = 0; i4 < sampleCount4; i4 += 1) { + float x0 = src[i+0]; + float x1 = src[i+1]; + float x2 = src[i+2]; + float x3 = src[i+3]; + + x0 = ((x0 < -1) ? -1 : ((x0 > 1) ? 1 : x0)); + x1 = ((x1 < -1) ? -1 : ((x1 > 1) ? 1 : x1)); + x2 = ((x2 < -1) ? -1 : ((x2 > 1) ? 1 : x2)); + x3 = ((x3 < -1) ? -1 : ((x3 > 1) ? 1 : x3)); + + x0 = x0 * 32767.0f; + x1 = x1 * 32767.0f; + x2 = x2 * 32767.0f; + x3 = x3 * 32767.0f; + + dst[i+0] = (drmp3_int16)x0; + dst[i+1] = (drmp3_int16)x1; + dst[i+2] = (drmp3_int16)x2; + dst[i+3] = (drmp3_int16)x3; + + i += 4; + } + + /* Leftover. */ + for (; i < sampleCount; i += 1) { + float x = src[i]; + x = ((x < -1) ? -1 : ((x > 1) ? 1 : x)); /* clip */ + x = x * 32767.0f; /* -1..1 to -32767..32767 */ + + dst[i] = (drmp3_int16)x; + } +} +#endif + +#if !defined(DR_MP3_FLOAT_OUTPUT) +static void drmp3_s16_to_f32(float* dst, const drmp3_int16* src, drmp3_uint64 sampleCount) +{ + drmp3_uint64 i; + for (i = 0; i < sampleCount; i += 1) { + float x = (float)src[i]; + x = x * 0.000030517578125f; /* -32768..32767 to -1..0.999969482421875 */ + dst[i] = x; + } +} +#endif + + +static drmp3_uint64 drmp3_read_pcm_frames_raw(drmp3* pMP3, drmp3_uint64 framesToRead, void* pBufferOut) +{ + drmp3_uint64 totalFramesRead = 0; + + DRMP3_ASSERT(pMP3 != NULL); + DRMP3_ASSERT(pMP3->onRead != NULL); + + while (framesToRead > 0) { + drmp3_uint32 framesToConsume = (drmp3_uint32)DRMP3_MIN(pMP3->pcmFramesRemainingInMP3Frame, framesToRead); + if (pBufferOut != NULL) { + #if defined(DR_MP3_FLOAT_OUTPUT) + /* f32 */ + float* pFramesOutF32 = (float*)DRMP3_OFFSET_PTR(pBufferOut, sizeof(float) * totalFramesRead * pMP3->channels); + float* pFramesInF32 = (float*)DRMP3_OFFSET_PTR(&pMP3->pcmFrames[0], sizeof(float) * pMP3->pcmFramesConsumedInMP3Frame * pMP3->mp3FrameChannels); + DRMP3_COPY_MEMORY(pFramesOutF32, pFramesInF32, sizeof(float) * framesToConsume * pMP3->channels); + #else + /* s16 */ + drmp3_int16* pFramesOutS16 = (drmp3_int16*)DRMP3_OFFSET_PTR(pBufferOut, sizeof(drmp3_int16) * totalFramesRead * pMP3->channels); + drmp3_int16* pFramesInS16 = (drmp3_int16*)DRMP3_OFFSET_PTR(&pMP3->pcmFrames[0], sizeof(drmp3_int16) * pMP3->pcmFramesConsumedInMP3Frame * pMP3->mp3FrameChannels); + DRMP3_COPY_MEMORY(pFramesOutS16, pFramesInS16, sizeof(drmp3_int16) * framesToConsume * pMP3->channels); + #endif + } + + pMP3->currentPCMFrame += framesToConsume; + pMP3->pcmFramesConsumedInMP3Frame += framesToConsume; + pMP3->pcmFramesRemainingInMP3Frame -= framesToConsume; + totalFramesRead += framesToConsume; + framesToRead -= framesToConsume; + + if (framesToRead == 0) { + break; + } + + DRMP3_ASSERT(pMP3->pcmFramesRemainingInMP3Frame == 0); + + /* + At this point we have exhausted our in-memory buffer so we need to re-fill. Note that the sample rate may have changed + at this point which means we'll also need to update our sample rate conversion pipeline. + */ + if (drmp3_decode_next_frame(pMP3) == 0) { + break; + } + } + + return totalFramesRead; +} + + +DRMP3_API drmp3_uint64 drmp3_read_pcm_frames_f32(drmp3* pMP3, drmp3_uint64 framesToRead, float* pBufferOut) +{ + if (pMP3 == NULL || pMP3->onRead == NULL) { + return 0; + } + +#if defined(DR_MP3_FLOAT_OUTPUT) + /* Fast path. No conversion required. */ + return drmp3_read_pcm_frames_raw(pMP3, framesToRead, pBufferOut); +#else + /* Slow path. Convert from s16 to f32. */ + { + drmp3_int16 pTempS16[8192]; + drmp3_uint64 totalPCMFramesRead = 0; + + while (totalPCMFramesRead < framesToRead) { + drmp3_uint64 framesJustRead; + drmp3_uint64 framesRemaining = framesToRead - totalPCMFramesRead; + drmp3_uint64 framesToReadNow = DRMP3_COUNTOF(pTempS16) / pMP3->channels; + if (framesToReadNow > framesRemaining) { + framesToReadNow = framesRemaining; + } + + framesJustRead = drmp3_read_pcm_frames_raw(pMP3, framesToReadNow, pTempS16); + if (framesJustRead == 0) { + break; + } + + drmp3_s16_to_f32((float*)DRMP3_OFFSET_PTR(pBufferOut, sizeof(float) * totalPCMFramesRead * pMP3->channels), pTempS16, framesJustRead * pMP3->channels); + totalPCMFramesRead += framesJustRead; + } + + return totalPCMFramesRead; + } +#endif +} + +DRMP3_API drmp3_uint64 drmp3_read_pcm_frames_s16(drmp3* pMP3, drmp3_uint64 framesToRead, drmp3_int16* pBufferOut) +{ + if (pMP3 == NULL || pMP3->onRead == NULL) { + return 0; + } + +#if !defined(DR_MP3_FLOAT_OUTPUT) + /* Fast path. No conversion required. */ + return drmp3_read_pcm_frames_raw(pMP3, framesToRead, pBufferOut); +#else + /* Slow path. Convert from f32 to s16. */ + { + float pTempF32[4096]; + drmp3_uint64 totalPCMFramesRead = 0; + + while (totalPCMFramesRead < framesToRead) { + drmp3_uint64 framesJustRead; + drmp3_uint64 framesRemaining = framesToRead - totalPCMFramesRead; + drmp3_uint64 framesToReadNow = DRMP3_COUNTOF(pTempF32) / pMP3->channels; + if (framesToReadNow > framesRemaining) { + framesToReadNow = framesRemaining; + } + + framesJustRead = drmp3_read_pcm_frames_raw(pMP3, framesToReadNow, pTempF32); + if (framesJustRead == 0) { + break; + } + + drmp3_f32_to_s16((drmp3_int16*)DRMP3_OFFSET_PTR(pBufferOut, sizeof(drmp3_int16) * totalPCMFramesRead * pMP3->channels), pTempF32, framesJustRead * pMP3->channels); + totalPCMFramesRead += framesJustRead; + } + + return totalPCMFramesRead; + } +#endif +} + +static void drmp3_reset(drmp3* pMP3) +{ + DRMP3_ASSERT(pMP3 != NULL); + + pMP3->pcmFramesConsumedInMP3Frame = 0; + pMP3->pcmFramesRemainingInMP3Frame = 0; + pMP3->currentPCMFrame = 0; + pMP3->dataSize = 0; + pMP3->atEnd = DRMP3_FALSE; + drmp3dec_init(&pMP3->decoder); +} + +static drmp3_bool32 drmp3_seek_to_start_of_stream(drmp3* pMP3) +{ + DRMP3_ASSERT(pMP3 != NULL); + DRMP3_ASSERT(pMP3->onSeek != NULL); + + /* Seek to the start of the stream to begin with. */ + if (!drmp3__on_seek(pMP3, 0, drmp3_seek_origin_start)) { + return DRMP3_FALSE; + } + + /* Clear any cached data. */ + drmp3_reset(pMP3); + return DRMP3_TRUE; +} + + +static drmp3_bool32 drmp3_seek_forward_by_pcm_frames__brute_force(drmp3* pMP3, drmp3_uint64 frameOffset) +{ + drmp3_uint64 framesRead; + + /* + Just using a dumb read-and-discard for now. What would be nice is to parse only the header of the MP3 frame, and then skip over leading + frames without spending the time doing a full decode. I cannot see an easy way to do this in minimp3, however, so it may involve some + kind of manual processing. + */ +#if defined(DR_MP3_FLOAT_OUTPUT) + framesRead = drmp3_read_pcm_frames_f32(pMP3, frameOffset, NULL); +#else + framesRead = drmp3_read_pcm_frames_s16(pMP3, frameOffset, NULL); +#endif + if (framesRead != frameOffset) { + return DRMP3_FALSE; + } + + return DRMP3_TRUE; +} + +static drmp3_bool32 drmp3_seek_to_pcm_frame__brute_force(drmp3* pMP3, drmp3_uint64 frameIndex) +{ + DRMP3_ASSERT(pMP3 != NULL); + + if (frameIndex == pMP3->currentPCMFrame) { + return DRMP3_TRUE; + } + + /* + If we're moving foward we just read from where we're at. Otherwise we need to move back to the start of + the stream and read from the beginning. + */ + if (frameIndex < pMP3->currentPCMFrame) { + /* Moving backward. Move to the start of the stream and then move forward. */ + if (!drmp3_seek_to_start_of_stream(pMP3)) { + return DRMP3_FALSE; + } + } + + DRMP3_ASSERT(frameIndex >= pMP3->currentPCMFrame); + return drmp3_seek_forward_by_pcm_frames__brute_force(pMP3, (frameIndex - pMP3->currentPCMFrame)); +} + +static drmp3_bool32 drmp3_find_closest_seek_point(drmp3* pMP3, drmp3_uint64 frameIndex, drmp3_uint32* pSeekPointIndex) +{ + drmp3_uint32 iSeekPoint; + + DRMP3_ASSERT(pSeekPointIndex != NULL); + + *pSeekPointIndex = 0; + + if (frameIndex < pMP3->pSeekPoints[0].pcmFrameIndex) { + return DRMP3_FALSE; + } + + /* Linear search for simplicity to begin with while I'm getting this thing working. Once it's all working change this to a binary search. */ + for (iSeekPoint = 0; iSeekPoint < pMP3->seekPointCount; ++iSeekPoint) { + if (pMP3->pSeekPoints[iSeekPoint].pcmFrameIndex > frameIndex) { + break; /* Found it. */ + } + + *pSeekPointIndex = iSeekPoint; + } + + return DRMP3_TRUE; +} + +static drmp3_bool32 drmp3_seek_to_pcm_frame__seek_table(drmp3* pMP3, drmp3_uint64 frameIndex) +{ + drmp3_seek_point seekPoint; + drmp3_uint32 priorSeekPointIndex; + drmp3_uint16 iMP3Frame; + drmp3_uint64 leftoverFrames; + + DRMP3_ASSERT(pMP3 != NULL); + DRMP3_ASSERT(pMP3->pSeekPoints != NULL); + DRMP3_ASSERT(pMP3->seekPointCount > 0); + + /* If there is no prior seekpoint it means the target PCM frame comes before the first seek point. Just assume a seekpoint at the start of the file in this case. */ + if (drmp3_find_closest_seek_point(pMP3, frameIndex, &priorSeekPointIndex)) { + seekPoint = pMP3->pSeekPoints[priorSeekPointIndex]; + } else { + seekPoint.seekPosInBytes = 0; + seekPoint.pcmFrameIndex = 0; + seekPoint.mp3FramesToDiscard = 0; + seekPoint.pcmFramesToDiscard = 0; + } + + /* First thing to do is seek to the first byte of the relevant MP3 frame. */ + if (!drmp3__on_seek_64(pMP3, seekPoint.seekPosInBytes, drmp3_seek_origin_start)) { + return DRMP3_FALSE; /* Failed to seek. */ + } + + /* Clear any cached data. */ + drmp3_reset(pMP3); + + /* Whole MP3 frames need to be discarded first. */ + for (iMP3Frame = 0; iMP3Frame < seekPoint.mp3FramesToDiscard; ++iMP3Frame) { + drmp3_uint32 pcmFramesRead; + drmp3d_sample_t* pPCMFrames; + + /* Pass in non-null for the last frame because we want to ensure the sample rate converter is preloaded correctly. */ + pPCMFrames = NULL; + if (iMP3Frame == seekPoint.mp3FramesToDiscard-1) { + pPCMFrames = (drmp3d_sample_t*)pMP3->pcmFrames; + } + + /* We first need to decode the next frame. */ + pcmFramesRead = drmp3_decode_next_frame_ex(pMP3, pPCMFrames); + if (pcmFramesRead == 0) { + return DRMP3_FALSE; + } + } + + /* We seeked to an MP3 frame in the raw stream so we need to make sure the current PCM frame is set correctly. */ + pMP3->currentPCMFrame = seekPoint.pcmFrameIndex - seekPoint.pcmFramesToDiscard; + + /* + Now at this point we can follow the same process as the brute force technique where we just skip over unnecessary MP3 frames and then + read-and-discard at least 2 whole MP3 frames. + */ + leftoverFrames = frameIndex - pMP3->currentPCMFrame; + return drmp3_seek_forward_by_pcm_frames__brute_force(pMP3, leftoverFrames); +} + +DRMP3_API drmp3_bool32 drmp3_seek_to_pcm_frame(drmp3* pMP3, drmp3_uint64 frameIndex) +{ + if (pMP3 == NULL || pMP3->onSeek == NULL) { + return DRMP3_FALSE; + } + + if (frameIndex == 0) { + return drmp3_seek_to_start_of_stream(pMP3); + } + + /* Use the seek table if we have one. */ + if (pMP3->pSeekPoints != NULL && pMP3->seekPointCount > 0) { + return drmp3_seek_to_pcm_frame__seek_table(pMP3, frameIndex); + } else { + return drmp3_seek_to_pcm_frame__brute_force(pMP3, frameIndex); + } +} + +DRMP3_API drmp3_bool32 drmp3_get_mp3_and_pcm_frame_count(drmp3* pMP3, drmp3_uint64* pMP3FrameCount, drmp3_uint64* pPCMFrameCount) +{ + drmp3_uint64 currentPCMFrame; + drmp3_uint64 totalPCMFrameCount; + drmp3_uint64 totalMP3FrameCount; + + if (pMP3 == NULL) { + return DRMP3_FALSE; + } + + /* + The way this works is we move back to the start of the stream, iterate over each MP3 frame and calculate the frame count based + on our output sample rate, the seek back to the PCM frame we were sitting on before calling this function. + */ + + /* The stream must support seeking for this to work. */ + if (pMP3->onSeek == NULL) { + return DRMP3_FALSE; + } + + /* We'll need to seek back to where we were, so grab the PCM frame we're currently sitting on so we can restore later. */ + currentPCMFrame = pMP3->currentPCMFrame; + + if (!drmp3_seek_to_start_of_stream(pMP3)) { + return DRMP3_FALSE; + } + + totalPCMFrameCount = 0; + totalMP3FrameCount = 0; + + for (;;) { + drmp3_uint32 pcmFramesInCurrentMP3Frame; + + pcmFramesInCurrentMP3Frame = drmp3_decode_next_frame_ex(pMP3, NULL); + if (pcmFramesInCurrentMP3Frame == 0) { + break; + } + + totalPCMFrameCount += pcmFramesInCurrentMP3Frame; + totalMP3FrameCount += 1; + } + + /* Finally, we need to seek back to where we were. */ + if (!drmp3_seek_to_start_of_stream(pMP3)) { + return DRMP3_FALSE; + } + + if (!drmp3_seek_to_pcm_frame(pMP3, currentPCMFrame)) { + return DRMP3_FALSE; + } + + if (pMP3FrameCount != NULL) { + *pMP3FrameCount = totalMP3FrameCount; + } + if (pPCMFrameCount != NULL) { + *pPCMFrameCount = totalPCMFrameCount; + } + + return DRMP3_TRUE; +} + +DRMP3_API drmp3_uint64 drmp3_get_pcm_frame_count(drmp3* pMP3) +{ + drmp3_uint64 totalPCMFrameCount; + if (!drmp3_get_mp3_and_pcm_frame_count(pMP3, NULL, &totalPCMFrameCount)) { + return 0; + } + + return totalPCMFrameCount; +} + +DRMP3_API drmp3_uint64 drmp3_get_mp3_frame_count(drmp3* pMP3) +{ + drmp3_uint64 totalMP3FrameCount; + if (!drmp3_get_mp3_and_pcm_frame_count(pMP3, &totalMP3FrameCount, NULL)) { + return 0; + } + + return totalMP3FrameCount; +} + +static void drmp3__accumulate_running_pcm_frame_count(drmp3* pMP3, drmp3_uint32 pcmFrameCountIn, drmp3_uint64* pRunningPCMFrameCount, float* pRunningPCMFrameCountFractionalPart) +{ + float srcRatio; + float pcmFrameCountOutF; + drmp3_uint32 pcmFrameCountOut; + + srcRatio = (float)pMP3->mp3FrameSampleRate / (float)pMP3->sampleRate; + DRMP3_ASSERT(srcRatio > 0); + + pcmFrameCountOutF = *pRunningPCMFrameCountFractionalPart + (pcmFrameCountIn / srcRatio); + pcmFrameCountOut = (drmp3_uint32)pcmFrameCountOutF; + *pRunningPCMFrameCountFractionalPart = pcmFrameCountOutF - pcmFrameCountOut; + *pRunningPCMFrameCount += pcmFrameCountOut; +} + +typedef struct +{ + drmp3_uint64 bytePos; + drmp3_uint64 pcmFrameIndex; /* <-- After sample rate conversion. */ +} drmp3__seeking_mp3_frame_info; + +DRMP3_API drmp3_bool32 drmp3_calculate_seek_points(drmp3* pMP3, drmp3_uint32* pSeekPointCount, drmp3_seek_point* pSeekPoints) +{ + drmp3_uint32 seekPointCount; + drmp3_uint64 currentPCMFrame; + drmp3_uint64 totalMP3FrameCount; + drmp3_uint64 totalPCMFrameCount; + + if (pMP3 == NULL || pSeekPointCount == NULL || pSeekPoints == NULL) { + return DRMP3_FALSE; /* Invalid args. */ + } + + seekPointCount = *pSeekPointCount; + if (seekPointCount == 0) { + return DRMP3_FALSE; /* The client has requested no seek points. Consider this to be invalid arguments since the client has probably not intended this. */ + } + + /* We'll need to seek back to the current sample after calculating the seekpoints so we need to go ahead and grab the current location at the top. */ + currentPCMFrame = pMP3->currentPCMFrame; + + /* We never do more than the total number of MP3 frames and we limit it to 32-bits. */ + if (!drmp3_get_mp3_and_pcm_frame_count(pMP3, &totalMP3FrameCount, &totalPCMFrameCount)) { + return DRMP3_FALSE; + } + + /* If there's less than DRMP3_SEEK_LEADING_MP3_FRAMES+1 frames we just report 1 seek point which will be the very start of the stream. */ + if (totalMP3FrameCount < DRMP3_SEEK_LEADING_MP3_FRAMES+1) { + seekPointCount = 1; + pSeekPoints[0].seekPosInBytes = 0; + pSeekPoints[0].pcmFrameIndex = 0; + pSeekPoints[0].mp3FramesToDiscard = 0; + pSeekPoints[0].pcmFramesToDiscard = 0; + } else { + drmp3_uint64 pcmFramesBetweenSeekPoints; + drmp3__seeking_mp3_frame_info mp3FrameInfo[DRMP3_SEEK_LEADING_MP3_FRAMES+1]; + drmp3_uint64 runningPCMFrameCount = 0; + float runningPCMFrameCountFractionalPart = 0; + drmp3_uint64 nextTargetPCMFrame; + drmp3_uint32 iMP3Frame; + drmp3_uint32 iSeekPoint; + + if (seekPointCount > totalMP3FrameCount-1) { + seekPointCount = (drmp3_uint32)totalMP3FrameCount-1; + } + + pcmFramesBetweenSeekPoints = totalPCMFrameCount / (seekPointCount+1); + + /* + Here is where we actually calculate the seek points. We need to start by moving the start of the stream. We then enumerate over each + MP3 frame. + */ + if (!drmp3_seek_to_start_of_stream(pMP3)) { + return DRMP3_FALSE; + } + + /* + We need to cache the byte positions of the previous MP3 frames. As a new MP3 frame is iterated, we cycle the byte positions in this + array. The value in the first item in this array is the byte position that will be reported in the next seek point. + */ + + /* We need to initialize the array of MP3 byte positions for the leading MP3 frames. */ + for (iMP3Frame = 0; iMP3Frame < DRMP3_SEEK_LEADING_MP3_FRAMES+1; ++iMP3Frame) { + drmp3_uint32 pcmFramesInCurrentMP3FrameIn; + + /* The byte position of the next frame will be the stream's cursor position, minus whatever is sitting in the buffer. */ + DRMP3_ASSERT(pMP3->streamCursor >= pMP3->dataSize); + mp3FrameInfo[iMP3Frame].bytePos = pMP3->streamCursor - pMP3->dataSize; + mp3FrameInfo[iMP3Frame].pcmFrameIndex = runningPCMFrameCount; + + /* We need to get information about this frame so we can know how many samples it contained. */ + pcmFramesInCurrentMP3FrameIn = drmp3_decode_next_frame_ex(pMP3, NULL); + if (pcmFramesInCurrentMP3FrameIn == 0) { + return DRMP3_FALSE; /* This should never happen. */ + } + + drmp3__accumulate_running_pcm_frame_count(pMP3, pcmFramesInCurrentMP3FrameIn, &runningPCMFrameCount, &runningPCMFrameCountFractionalPart); + } + + /* + At this point we will have extracted the byte positions of the leading MP3 frames. We can now start iterating over each seek point and + calculate them. + */ + nextTargetPCMFrame = 0; + for (iSeekPoint = 0; iSeekPoint < seekPointCount; ++iSeekPoint) { + nextTargetPCMFrame += pcmFramesBetweenSeekPoints; + + for (;;) { + if (nextTargetPCMFrame < runningPCMFrameCount) { + /* The next seek point is in the current MP3 frame. */ + pSeekPoints[iSeekPoint].seekPosInBytes = mp3FrameInfo[0].bytePos; + pSeekPoints[iSeekPoint].pcmFrameIndex = nextTargetPCMFrame; + pSeekPoints[iSeekPoint].mp3FramesToDiscard = DRMP3_SEEK_LEADING_MP3_FRAMES; + pSeekPoints[iSeekPoint].pcmFramesToDiscard = (drmp3_uint16)(nextTargetPCMFrame - mp3FrameInfo[DRMP3_SEEK_LEADING_MP3_FRAMES-1].pcmFrameIndex); + break; + } else { + size_t i; + drmp3_uint32 pcmFramesInCurrentMP3FrameIn; + + /* + The next seek point is not in the current MP3 frame, so continue on to the next one. The first thing to do is cycle the cached + MP3 frame info. + */ + for (i = 0; i < DRMP3_COUNTOF(mp3FrameInfo)-1; ++i) { + mp3FrameInfo[i] = mp3FrameInfo[i+1]; + } + + /* Cache previous MP3 frame info. */ + mp3FrameInfo[DRMP3_COUNTOF(mp3FrameInfo)-1].bytePos = pMP3->streamCursor - pMP3->dataSize; + mp3FrameInfo[DRMP3_COUNTOF(mp3FrameInfo)-1].pcmFrameIndex = runningPCMFrameCount; + + /* + Go to the next MP3 frame. This shouldn't ever fail, but just in case it does we just set the seek point and break. If it happens, it + should only ever do it for the last seek point. + */ + pcmFramesInCurrentMP3FrameIn = drmp3_decode_next_frame_ex(pMP3, NULL); + if (pcmFramesInCurrentMP3FrameIn == 0) { + pSeekPoints[iSeekPoint].seekPosInBytes = mp3FrameInfo[0].bytePos; + pSeekPoints[iSeekPoint].pcmFrameIndex = nextTargetPCMFrame; + pSeekPoints[iSeekPoint].mp3FramesToDiscard = DRMP3_SEEK_LEADING_MP3_FRAMES; + pSeekPoints[iSeekPoint].pcmFramesToDiscard = (drmp3_uint16)(nextTargetPCMFrame - mp3FrameInfo[DRMP3_SEEK_LEADING_MP3_FRAMES-1].pcmFrameIndex); + break; + } + + drmp3__accumulate_running_pcm_frame_count(pMP3, pcmFramesInCurrentMP3FrameIn, &runningPCMFrameCount, &runningPCMFrameCountFractionalPart); + } + } + } + + /* Finally, we need to seek back to where we were. */ + if (!drmp3_seek_to_start_of_stream(pMP3)) { + return DRMP3_FALSE; + } + if (!drmp3_seek_to_pcm_frame(pMP3, currentPCMFrame)) { + return DRMP3_FALSE; + } + } + + *pSeekPointCount = seekPointCount; + return DRMP3_TRUE; +} + +DRMP3_API drmp3_bool32 drmp3_bind_seek_table(drmp3* pMP3, drmp3_uint32 seekPointCount, drmp3_seek_point* pSeekPoints) +{ + if (pMP3 == NULL) { + return DRMP3_FALSE; + } + + if (seekPointCount == 0 || pSeekPoints == NULL) { + /* Unbinding. */ + pMP3->seekPointCount = 0; + pMP3->pSeekPoints = NULL; + } else { + /* Binding. */ + pMP3->seekPointCount = seekPointCount; + pMP3->pSeekPoints = pSeekPoints; + } + + return DRMP3_TRUE; +} + + +static float* drmp3__full_read_and_close_f32(drmp3* pMP3, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount) +{ + drmp3_uint64 totalFramesRead = 0; + drmp3_uint64 framesCapacity = 0; + float* pFrames = NULL; + float temp[4096]; + + DRMP3_ASSERT(pMP3 != NULL); + + for (;;) { + drmp3_uint64 framesToReadRightNow = DRMP3_COUNTOF(temp) / pMP3->channels; + drmp3_uint64 framesJustRead = drmp3_read_pcm_frames_f32(pMP3, framesToReadRightNow, temp); + if (framesJustRead == 0) { + break; + } + + /* Reallocate the output buffer if there's not enough room. */ + if (framesCapacity < totalFramesRead + framesJustRead) { + drmp3_uint64 oldFramesBufferSize; + drmp3_uint64 newFramesBufferSize; + drmp3_uint64 newFramesCap; + float* pNewFrames; + + newFramesCap = framesCapacity * 2; + if (newFramesCap < totalFramesRead + framesJustRead) { + newFramesCap = totalFramesRead + framesJustRead; + } + + oldFramesBufferSize = framesCapacity * pMP3->channels * sizeof(float); + newFramesBufferSize = newFramesCap * pMP3->channels * sizeof(float); + if (newFramesBufferSize > DRMP3_SIZE_MAX) { + break; + } + + pNewFrames = (float*)drmp3__realloc_from_callbacks(pFrames, (size_t)newFramesBufferSize, (size_t)oldFramesBufferSize, &pMP3->allocationCallbacks); + if (pNewFrames == NULL) { + drmp3__free_from_callbacks(pFrames, &pMP3->allocationCallbacks); + break; + } + + pFrames = pNewFrames; + framesCapacity = newFramesCap; + } + + DRMP3_COPY_MEMORY(pFrames + totalFramesRead*pMP3->channels, temp, (size_t)(framesJustRead*pMP3->channels*sizeof(float))); + totalFramesRead += framesJustRead; + + /* If the number of frames we asked for is less that what we actually read it means we've reached the end. */ + if (framesJustRead != framesToReadRightNow) { + break; + } + } + + if (pConfig != NULL) { + pConfig->channels = pMP3->channels; + pConfig->sampleRate = pMP3->sampleRate; + } + + drmp3_uninit(pMP3); + + if (pTotalFrameCount) { + *pTotalFrameCount = totalFramesRead; + } + + return pFrames; +} + +static drmp3_int16* drmp3__full_read_and_close_s16(drmp3* pMP3, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount) +{ + drmp3_uint64 totalFramesRead = 0; + drmp3_uint64 framesCapacity = 0; + drmp3_int16* pFrames = NULL; + drmp3_int16 temp[4096]; + + DRMP3_ASSERT(pMP3 != NULL); + + for (;;) { + drmp3_uint64 framesToReadRightNow = DRMP3_COUNTOF(temp) / pMP3->channels; + drmp3_uint64 framesJustRead = drmp3_read_pcm_frames_s16(pMP3, framesToReadRightNow, temp); + if (framesJustRead == 0) { + break; + } + + /* Reallocate the output buffer if there's not enough room. */ + if (framesCapacity < totalFramesRead + framesJustRead) { + drmp3_uint64 newFramesBufferSize; + drmp3_uint64 oldFramesBufferSize; + drmp3_uint64 newFramesCap; + drmp3_int16* pNewFrames; + + newFramesCap = framesCapacity * 2; + if (newFramesCap < totalFramesRead + framesJustRead) { + newFramesCap = totalFramesRead + framesJustRead; + } + + oldFramesBufferSize = framesCapacity * pMP3->channels * sizeof(drmp3_int16); + newFramesBufferSize = newFramesCap * pMP3->channels * sizeof(drmp3_int16); + if (newFramesBufferSize > DRMP3_SIZE_MAX) { + break; + } + + pNewFrames = (drmp3_int16*)drmp3__realloc_from_callbacks(pFrames, (size_t)newFramesBufferSize, (size_t)oldFramesBufferSize, &pMP3->allocationCallbacks); + if (pNewFrames == NULL) { + drmp3__free_from_callbacks(pFrames, &pMP3->allocationCallbacks); + break; + } + + pFrames = pNewFrames; + framesCapacity = newFramesCap; + } + + DRMP3_COPY_MEMORY(pFrames + totalFramesRead*pMP3->channels, temp, (size_t)(framesJustRead*pMP3->channels*sizeof(drmp3_int16))); + totalFramesRead += framesJustRead; + + /* If the number of frames we asked for is less that what we actually read it means we've reached the end. */ + if (framesJustRead != framesToReadRightNow) { + break; + } + } + + if (pConfig != NULL) { + pConfig->channels = pMP3->channels; + pConfig->sampleRate = pMP3->sampleRate; + } + + drmp3_uninit(pMP3); + + if (pTotalFrameCount) { + *pTotalFrameCount = totalFramesRead; + } + + return pFrames; +} + + +DRMP3_API float* drmp3_open_and_read_pcm_frames_f32(drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks) +{ + drmp3 mp3; + if (!drmp3_init(&mp3, onRead, onSeek, pUserData, pAllocationCallbacks)) { + return NULL; + } + + return drmp3__full_read_and_close_f32(&mp3, pConfig, pTotalFrameCount); +} + +DRMP3_API drmp3_int16* drmp3_open_and_read_pcm_frames_s16(drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks) +{ + drmp3 mp3; + if (!drmp3_init(&mp3, onRead, onSeek, pUserData, pAllocationCallbacks)) { + return NULL; + } + + return drmp3__full_read_and_close_s16(&mp3, pConfig, pTotalFrameCount); +} + + +DRMP3_API float* drmp3_open_memory_and_read_pcm_frames_f32(const void* pData, size_t dataSize, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks) +{ + drmp3 mp3; + if (!drmp3_init_memory(&mp3, pData, dataSize, pAllocationCallbacks)) { + return NULL; + } + + return drmp3__full_read_and_close_f32(&mp3, pConfig, pTotalFrameCount); +} + +DRMP3_API drmp3_int16* drmp3_open_memory_and_read_pcm_frames_s16(const void* pData, size_t dataSize, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks) +{ + drmp3 mp3; + if (!drmp3_init_memory(&mp3, pData, dataSize, pAllocationCallbacks)) { + return NULL; + } + + return drmp3__full_read_and_close_s16(&mp3, pConfig, pTotalFrameCount); +} + + +#ifndef DR_MP3_NO_STDIO +DRMP3_API float* drmp3_open_file_and_read_pcm_frames_f32(const char* filePath, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks) +{ + drmp3 mp3; + if (!drmp3_init_file(&mp3, filePath, pAllocationCallbacks)) { + return NULL; + } + + return drmp3__full_read_and_close_f32(&mp3, pConfig, pTotalFrameCount); +} + +DRMP3_API drmp3_int16* drmp3_open_file_and_read_pcm_frames_s16(const char* filePath, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks) +{ + drmp3 mp3; + if (!drmp3_init_file(&mp3, filePath, pAllocationCallbacks)) { + return NULL; + } + + return drmp3__full_read_and_close_s16(&mp3, pConfig, pTotalFrameCount); +} +#endif + +DRMP3_API void* drmp3_malloc(size_t sz, const drmp3_allocation_callbacks* pAllocationCallbacks) +{ + if (pAllocationCallbacks != NULL) { + return drmp3__malloc_from_callbacks(sz, pAllocationCallbacks); + } else { + return drmp3__malloc_default(sz, NULL); + } +} + +DRMP3_API void drmp3_free(void* p, const drmp3_allocation_callbacks* pAllocationCallbacks) +{ + if (pAllocationCallbacks != NULL) { + drmp3__free_from_callbacks(p, pAllocationCallbacks); + } else { + drmp3__free_default(p, NULL); + } +} + +#endif /* dr_mp3_c */ +#endif /*DR_MP3_IMPLEMENTATION*/ + +/* +DIFFERENCES BETWEEN minimp3 AND dr_mp3 +====================================== +- First, keep in mind that minimp3 (https://github.com/lieff/minimp3) is where all the real work was done. All of the + code relating to the actual decoding remains mostly unmodified, apart from some namespacing changes. +- dr_mp3 adds a pulling style API which allows you to deliver raw data via callbacks. So, rather than pushing data + to the decoder, the decoder _pulls_ data from your callbacks. +- In addition to callbacks, a decoder can be initialized from a block of memory and a file. +- The dr_mp3 pull API reads PCM frames rather than whole MP3 frames. +- dr_mp3 adds convenience APIs for opening and decoding entire files in one go. +- dr_mp3 is fully namespaced, including the implementation section, which is more suitable when compiling projects + as a single translation unit (aka unity builds). At the time of writing this, a unity build is not possible when + using minimp3 in conjunction with stb_vorbis. dr_mp3 addresses this. +*/ + +/* +RELEASE NOTES - v0.5.0 +======================= +Version 0.5.0 has breaking API changes. + +Improved Client-Defined Memory Allocation +----------------------------------------- +The main change with this release is the addition of a more flexible way of implementing custom memory allocation routines. The +existing system of DRMP3_MALLOC, DRMP3_REALLOC and DRMP3_FREE are still in place and will be used by default when no custom +allocation callbacks are specified. + +To use the new system, you pass in a pointer to a drmp3_allocation_callbacks object to drmp3_init() and family, like this: + + void* my_malloc(size_t sz, void* pUserData) + { + return malloc(sz); + } + void* my_realloc(void* p, size_t sz, void* pUserData) + { + return realloc(p, sz); + } + void my_free(void* p, void* pUserData) + { + free(p); + } + + ... + + drmp3_allocation_callbacks allocationCallbacks; + allocationCallbacks.pUserData = &myData; + allocationCallbacks.onMalloc = my_malloc; + allocationCallbacks.onRealloc = my_realloc; + allocationCallbacks.onFree = my_free; + drmp3_init_file(&mp3, "my_file.mp3", NULL, &allocationCallbacks); + +The advantage of this new system is that it allows you to specify user data which will be passed in to the allocation routines. + +Passing in null for the allocation callbacks object will cause dr_mp3 to use defaults which is the same as DRMP3_MALLOC, +DRMP3_REALLOC and DRMP3_FREE and the equivalent of how it worked in previous versions. + +Every API that opens a drmp3 object now takes this extra parameter. These include the following: + + drmp3_init() + drmp3_init_file() + drmp3_init_memory() + drmp3_open_and_read_pcm_frames_f32() + drmp3_open_and_read_pcm_frames_s16() + drmp3_open_memory_and_read_pcm_frames_f32() + drmp3_open_memory_and_read_pcm_frames_s16() + drmp3_open_file_and_read_pcm_frames_f32() + drmp3_open_file_and_read_pcm_frames_s16() + +Renamed APIs +------------ +The following APIs have been renamed for consistency with other dr_* libraries and to make it clear that they return PCM frame +counts rather than sample counts. + + drmp3_open_and_read_f32() -> drmp3_open_and_read_pcm_frames_f32() + drmp3_open_and_read_s16() -> drmp3_open_and_read_pcm_frames_s16() + drmp3_open_memory_and_read_f32() -> drmp3_open_memory_and_read_pcm_frames_f32() + drmp3_open_memory_and_read_s16() -> drmp3_open_memory_and_read_pcm_frames_s16() + drmp3_open_file_and_read_f32() -> drmp3_open_file_and_read_pcm_frames_f32() + drmp3_open_file_and_read_s16() -> drmp3_open_file_and_read_pcm_frames_s16() +*/ + +/* +REVISION HISTORY +================ +v0.6.27 - 2021-02-21 + - Fix a warning due to referencing _MSC_VER when it is undefined. + +v0.6.26 - 2021-01-31 + - Bring up to date with minimp3. + +v0.6.25 - 2020-12-26 + - Remove DRMP3_DEFAULT_CHANNELS and DRMP3_DEFAULT_SAMPLE_RATE which are leftovers from some removed APIs. + +v0.6.24 - 2020-12-07 + - Fix a typo in version date for 0.6.23. + +v0.6.23 - 2020-12-03 + - Fix an error where a file can be closed twice when initialization of the decoder fails. + +v0.6.22 - 2020-12-02 + - Fix an error where it's possible for a file handle to be left open when initialization of the decoder fails. + +v0.6.21 - 2020-11-28 + - Bring up to date with minimp3. + +v0.6.20 - 2020-11-21 + - Fix compilation with OpenWatcom. + +v0.6.19 - 2020-11-13 + - Minor code clean up. + +v0.6.18 - 2020-11-01 + - Improve compiler support for older versions of GCC. + +v0.6.17 - 2020-09-28 + - Bring up to date with minimp3. + +v0.6.16 - 2020-08-02 + - Simplify sized types. + +v0.6.15 - 2020-07-25 + - Fix a compilation warning. + +v0.6.14 - 2020-07-23 + - Fix undefined behaviour with memmove(). + +v0.6.13 - 2020-07-06 + - Fix a bug when converting from s16 to f32 in drmp3_read_pcm_frames_f32(). + +v0.6.12 - 2020-06-23 + - Add include guard for the implementation section. + +v0.6.11 - 2020-05-26 + - Fix use of uninitialized variable error. + +v0.6.10 - 2020-05-16 + - Add compile-time and run-time version querying. + - DRMP3_VERSION_MINOR + - DRMP3_VERSION_MAJOR + - DRMP3_VERSION_REVISION + - DRMP3_VERSION_STRING + - drmp3_version() + - drmp3_version_string() + +v0.6.9 - 2020-04-30 + - Change the `pcm` parameter of drmp3dec_decode_frame() to a `const drmp3_uint8*` for consistency with internal APIs. + +v0.6.8 - 2020-04-26 + - Optimizations to decoding when initializing from memory. + +v0.6.7 - 2020-04-25 + - Fix a compilation error with DR_MP3_NO_STDIO + - Optimization to decoding by reducing some data movement. + +v0.6.6 - 2020-04-23 + - Fix a minor bug with the running PCM frame counter. + +v0.6.5 - 2020-04-19 + - Fix compilation error on ARM builds. + +v0.6.4 - 2020-04-19 + - Bring up to date with changes to minimp3. + +v0.6.3 - 2020-04-13 + - Fix some pedantic warnings. + +v0.6.2 - 2020-04-10 + - Fix a crash in drmp3_open_*_and_read_pcm_frames_*() if the output config object is NULL. + +v0.6.1 - 2020-04-05 + - Fix warnings. + +v0.6.0 - 2020-04-04 + - API CHANGE: Remove the pConfig parameter from the following APIs: + - drmp3_init() + - drmp3_init_memory() + - drmp3_init_file() + - Add drmp3_init_file_w() for opening a file from a wchar_t encoded path. + +v0.5.6 - 2020-02-12 + - Bring up to date with minimp3. + +v0.5.5 - 2020-01-29 + - Fix a memory allocation bug in high level s16 decoding APIs. + +v0.5.4 - 2019-12-02 + - Fix a possible null pointer dereference when using custom memory allocators for realloc(). + +v0.5.3 - 2019-11-14 + - Fix typos in documentation. + +v0.5.2 - 2019-11-02 + - Bring up to date with minimp3. + +v0.5.1 - 2019-10-08 + - Fix a warning with GCC. + +v0.5.0 - 2019-10-07 + - API CHANGE: Add support for user defined memory allocation routines. This system allows the program to specify their own memory allocation + routines with a user data pointer for client-specific contextual data. This adds an extra parameter to the end of the following APIs: + - drmp3_init() + - drmp3_init_file() + - drmp3_init_memory() + - drmp3_open_and_read_pcm_frames_f32() + - drmp3_open_and_read_pcm_frames_s16() + - drmp3_open_memory_and_read_pcm_frames_f32() + - drmp3_open_memory_and_read_pcm_frames_s16() + - drmp3_open_file_and_read_pcm_frames_f32() + - drmp3_open_file_and_read_pcm_frames_s16() + - API CHANGE: Renamed the following APIs: + - drmp3_open_and_read_f32() -> drmp3_open_and_read_pcm_frames_f32() + - drmp3_open_and_read_s16() -> drmp3_open_and_read_pcm_frames_s16() + - drmp3_open_memory_and_read_f32() -> drmp3_open_memory_and_read_pcm_frames_f32() + - drmp3_open_memory_and_read_s16() -> drmp3_open_memory_and_read_pcm_frames_s16() + - drmp3_open_file_and_read_f32() -> drmp3_open_file_and_read_pcm_frames_f32() + - drmp3_open_file_and_read_s16() -> drmp3_open_file_and_read_pcm_frames_s16() + +v0.4.7 - 2019-07-28 + - Fix a compiler error. + +v0.4.6 - 2019-06-14 + - Fix a compiler error. + +v0.4.5 - 2019-06-06 + - Bring up to date with minimp3. + +v0.4.4 - 2019-05-06 + - Fixes to the VC6 build. + +v0.4.3 - 2019-05-05 + - Use the channel count and/or sample rate of the first MP3 frame instead of DRMP3_DEFAULT_CHANNELS and + DRMP3_DEFAULT_SAMPLE_RATE when they are set to 0. To use the old behaviour, just set the relevant property to + DRMP3_DEFAULT_CHANNELS or DRMP3_DEFAULT_SAMPLE_RATE. + - Add s16 reading APIs + - drmp3_read_pcm_frames_s16 + - drmp3_open_memory_and_read_pcm_frames_s16 + - drmp3_open_and_read_pcm_frames_s16 + - drmp3_open_file_and_read_pcm_frames_s16 + - Add drmp3_get_mp3_and_pcm_frame_count() to the public header section. + - Add support for C89. + - Change license to choice of public domain or MIT-0. + +v0.4.2 - 2019-02-21 + - Fix a warning. + +v0.4.1 - 2018-12-30 + - Fix a warning. + +v0.4.0 - 2018-12-16 + - API CHANGE: Rename some APIs: + - drmp3_read_f32 -> to drmp3_read_pcm_frames_f32 + - drmp3_seek_to_frame -> drmp3_seek_to_pcm_frame + - drmp3_open_and_decode_f32 -> drmp3_open_and_read_pcm_frames_f32 + - drmp3_open_and_decode_memory_f32 -> drmp3_open_memory_and_read_pcm_frames_f32 + - drmp3_open_and_decode_file_f32 -> drmp3_open_file_and_read_pcm_frames_f32 + - Add drmp3_get_pcm_frame_count(). + - Add drmp3_get_mp3_frame_count(). + - Improve seeking performance. + +v0.3.2 - 2018-09-11 + - Fix a couple of memory leaks. + - Bring up to date with minimp3. + +v0.3.1 - 2018-08-25 + - Fix C++ build. + +v0.3.0 - 2018-08-25 + - Bring up to date with minimp3. This has a minor API change: the "pcm" parameter of drmp3dec_decode_frame() has + been changed from short* to void* because it can now output both s16 and f32 samples, depending on whether or + not the DR_MP3_FLOAT_OUTPUT option is set. + +v0.2.11 - 2018-08-08 + - Fix a bug where the last part of a file is not read. + +v0.2.10 - 2018-08-07 + - Improve 64-bit detection. + +v0.2.9 - 2018-08-05 + - Fix C++ build on older versions of GCC. + - Bring up to date with minimp3. + +v0.2.8 - 2018-08-02 + - Fix compilation errors with older versions of GCC. + +v0.2.7 - 2018-07-13 + - Bring up to date with minimp3. + +v0.2.6 - 2018-07-12 + - Bring up to date with minimp3. + +v0.2.5 - 2018-06-22 + - Bring up to date with minimp3. + +v0.2.4 - 2018-05-12 + - Bring up to date with minimp3. + +v0.2.3 - 2018-04-29 + - Fix TCC build. + +v0.2.2 - 2018-04-28 + - Fix bug when opening a decoder from memory. + +v0.2.1 - 2018-04-27 + - Efficiency improvements when the decoder reaches the end of the stream. + +v0.2 - 2018-04-21 + - Bring up to date with minimp3. + - Start using major.minor.revision versioning. + +v0.1d - 2018-03-30 + - Bring up to date with minimp3. + +v0.1c - 2018-03-11 + - Fix C++ build error. + +v0.1b - 2018-03-07 + - Bring up to date with minimp3. + +v0.1a - 2018-02-28 + - Fix compilation error on GCC/Clang. + - Fix some warnings. + +v0.1 - 2018-02-xx + - Initial versioned release. +*/ + +/* +This software is available as a choice of the following licenses. Choose +whichever you prefer. + +=============================================================================== +ALTERNATIVE 1 - Public Domain (www.unlicense.org) +=============================================================================== +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or distribute this +software, either in source code form or as a compiled binary, for any purpose, +commercial or non-commercial, and by any means. + +In jurisdictions that recognize copyright laws, the author or authors of this +software dedicate any and all copyright interest in the software to the public +domain. We make this dedication for the benefit of the public at large and to +the detriment of our heirs and successors. We intend this dedication to be an +overt act of relinquishment in perpetuity of all present and future rights to +this software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to + +=============================================================================== +ALTERNATIVE 2 - MIT No Attribution +=============================================================================== +Copyright 2020 David Reid + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +/* + https://github.com/lieff/minimp3 + To the extent possible under law, the author(s) have dedicated all copyright and related and neighboring rights to this software to the public domain worldwide. + This software is distributed without any warranty. + See . +*/ From 327226f6e6d52626998fcfc0eed22ebd3dd4fc8e Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 7 Jun 2021 15:50:53 -0400 Subject: [PATCH 022/606] Make a gigantic stack allocation static. This is only safe because we only decode one mp3 at a time, but cleaning this up more properly would be good. Should prevent MSVC from inserting a call to _chkstk here. --- src/dr_mp3.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dr_mp3.h b/src/dr_mp3.h index e28f318bc..0cbeab10e 100644 --- a/src/dr_mp3.h +++ b/src/dr_mp3.h @@ -2218,7 +2218,7 @@ DRMP3_API int drmp3dec_decode_frame(drmp3dec *dec, const drmp3_uint8 *mp3, int m int i = 0, igr, frame_size = 0, success = 1; const drmp3_uint8 *hdr; drmp3_bs bs_frame[1]; - drmp3dec_scratch scratch; + static drmp3dec_scratch scratch; if (mp3_bytes > 4 && dec->header[0] == 0xff && drmp3_hdr_compare(dec->header, mp3)) { From 2246fe21b5a781f5b0895fe753cd1b10fcfb6d19 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 7 Jun 2021 16:33:39 -0400 Subject: [PATCH 023/606] Forcibly remove the sint16 MP3 decoding path. Removes some large stack allocations that upset MSVC. --- src/SDL12_compat.c | 1 + src/dr_mp3.h | 32 ++++++++++++++++++++++++++------ 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 7b72fce21..991213871 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -5692,6 +5692,7 @@ SDL_LoadWAV_RW(SDL12_RWops *rwops12, int freerwops12, /* public domain, single-header MP3 decoder for fake CD-ROM audio support! */ #define DR_MP3_IMPLEMENTATION #define DR_MP3_NO_STDIO 1 +#define DR_MP3_NO_S16 1 #define DR_MP3_FLOAT_OUTPUT 1 #define DRMP3_ASSERT(x) SDL_assert((x)) #define DRMP3_MALLOC(sz) SDL20_malloc((sz)) diff --git a/src/dr_mp3.h b/src/dr_mp3.h index 0cbeab10e..ff673fd62 100644 --- a/src/dr_mp3.h +++ b/src/dr_mp3.h @@ -90,6 +90,12 @@ Build Options extern "C" { #endif +#ifndef DR_MP3_NO_S16 +#ifndef DR_MP3_FLOAT_OUTPUT +#define DR_MP3_FLOAT_OUTPUT +#endif +#endif + #define DRMP3_STRINGIFY(x) #x #define DRMP3_XSTRINGIFY(x) DRMP3_STRINGIFY(x) @@ -272,9 +278,10 @@ DRMP3_API void drmp3dec_init(drmp3dec *dec); /* Reads a frame from a low level decoder. */ DRMP3_API int drmp3dec_decode_frame(drmp3dec *dec, const drmp3_uint8 *mp3, int mp3_bytes, void *pcm, drmp3dec_frame_info *info); +#ifndef DR_MP3_NO_S16 /* Helper for converting between f32 and s16. */ DRMP3_API void drmp3dec_f32_to_s16(const float *in, drmp3_int16 *out, size_t num_samples); - +#endif /* @@ -418,12 +425,14 @@ Note that framesToRead specifies the number of PCM frames to read, _not_ the num */ DRMP3_API drmp3_uint64 drmp3_read_pcm_frames_f32(drmp3* pMP3, drmp3_uint64 framesToRead, float* pBufferOut); +#ifndef DR_MP3_NO_S16 /* Reads PCM frames as interleaved signed 16-bit integer PCM. Note that framesToRead specifies the number of PCM frames to read, _not_ the number of MP3 frames. */ DRMP3_API drmp3_uint64 drmp3_read_pcm_frames_s16(drmp3* pMP3, drmp3_uint64 framesToRead, drmp3_int16* pBufferOut); +#endif /* Seeks to a specific frame. @@ -482,15 +491,21 @@ On output pConfig will receive the channel count and sample rate of the stream. Free the returned pointer with drmp3_free(). */ DRMP3_API float* drmp3_open_and_read_pcm_frames_f32(drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks); +#ifndef DR_MP3_NO_S16 DRMP3_API drmp3_int16* drmp3_open_and_read_pcm_frames_s16(drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks); +#endif DRMP3_API float* drmp3_open_memory_and_read_pcm_frames_f32(const void* pData, size_t dataSize, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks); +#ifndef DR_MP3_NO_S16 DRMP3_API drmp3_int16* drmp3_open_memory_and_read_pcm_frames_s16(const void* pData, size_t dataSize, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks); +#endif #ifndef DR_MP3_NO_STDIO DRMP3_API float* drmp3_open_file_and_read_pcm_frames_f32(const char* filePath, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks); +#ifndef DR_MP3_NO_S16 DRMP3_API drmp3_int16* drmp3_open_file_and_read_pcm_frames_s16(const char* filePath, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks); #endif +#endif /* Allocates a block of memory on the heap. @@ -2308,6 +2323,7 @@ DRMP3_API int drmp3dec_decode_frame(drmp3dec *dec, const drmp3_uint8 *mp3, int m return success*drmp3_hdr_frame_samples(dec->header); } +#ifndef DR_MP3_NO_S16 DRMP3_API void drmp3dec_f32_to_s16(const float *in, drmp3_int16 *out, size_t num_samples) { size_t i = 0; @@ -2363,7 +2379,7 @@ DRMP3_API void drmp3dec_f32_to_s16(const float *in, drmp3_int16 *out, size_t num } } } - +#endif /************************************************************************************************************************************************************ @@ -3590,7 +3606,6 @@ static void drmp3_s16_to_f32(float* dst, const drmp3_int16* src, drmp3_uint64 sa } #endif - static drmp3_uint64 drmp3_read_pcm_frames_raw(drmp3* pMP3, drmp3_uint64 framesToRead, void* pBufferOut) { drmp3_uint64 totalFramesRead = 0; @@ -4214,6 +4229,7 @@ static float* drmp3__full_read_and_close_f32(drmp3* pMP3, drmp3_config* pConfig, return pFrames; } +#ifndef DR_MP3_NO_S16 static drmp3_int16* drmp3__full_read_and_close_s16(drmp3* pMP3, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount) { drmp3_uint64 totalFramesRead = 0; @@ -4280,7 +4296,7 @@ static drmp3_int16* drmp3__full_read_and_close_s16(drmp3* pMP3, drmp3_config* pC return pFrames; } - +#endif DRMP3_API float* drmp3_open_and_read_pcm_frames_f32(drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks) { @@ -4292,6 +4308,7 @@ DRMP3_API float* drmp3_open_and_read_pcm_frames_f32(drmp3_read_proc onRead, drmp return drmp3__full_read_and_close_f32(&mp3, pConfig, pTotalFrameCount); } +#ifndef DR_MP3_NO_S16 DRMP3_API drmp3_int16* drmp3_open_and_read_pcm_frames_s16(drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks) { drmp3 mp3; @@ -4301,7 +4318,7 @@ DRMP3_API drmp3_int16* drmp3_open_and_read_pcm_frames_s16(drmp3_read_proc onRead return drmp3__full_read_and_close_s16(&mp3, pConfig, pTotalFrameCount); } - +#endif DRMP3_API float* drmp3_open_memory_and_read_pcm_frames_f32(const void* pData, size_t dataSize, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks) { @@ -4313,6 +4330,7 @@ DRMP3_API float* drmp3_open_memory_and_read_pcm_frames_f32(const void* pData, si return drmp3__full_read_and_close_f32(&mp3, pConfig, pTotalFrameCount); } +#ifndef DR_MP3_NO_S16 DRMP3_API drmp3_int16* drmp3_open_memory_and_read_pcm_frames_s16(const void* pData, size_t dataSize, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks) { drmp3 mp3; @@ -4322,7 +4340,7 @@ DRMP3_API drmp3_int16* drmp3_open_memory_and_read_pcm_frames_s16(const void* pDa return drmp3__full_read_and_close_s16(&mp3, pConfig, pTotalFrameCount); } - +#endif #ifndef DR_MP3_NO_STDIO DRMP3_API float* drmp3_open_file_and_read_pcm_frames_f32(const char* filePath, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks) @@ -4335,6 +4353,7 @@ DRMP3_API float* drmp3_open_file_and_read_pcm_frames_f32(const char* filePath, d return drmp3__full_read_and_close_f32(&mp3, pConfig, pTotalFrameCount); } +#ifndef DR_MP3_NO_S16 DRMP3_API drmp3_int16* drmp3_open_file_and_read_pcm_frames_s16(const char* filePath, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks) { drmp3 mp3; @@ -4345,6 +4364,7 @@ DRMP3_API drmp3_int16* drmp3_open_file_and_read_pcm_frames_s16(const char* fileP return drmp3__full_read_and_close_s16(&mp3, pConfig, pTotalFrameCount); } #endif +#endif DRMP3_API void* drmp3_malloc(size_t sz, const drmp3_allocation_callbacks* pAllocationCallbacks) { From bf366a12463dd468b0a7c1dc6d0c1c7dec1c08e2 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Mon, 7 Jun 2021 23:55:50 +0300 Subject: [PATCH 024/606] fix a stupid watcom warning. --- src/dr_mp3.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dr_mp3.h b/src/dr_mp3.h index ff673fd62..c280a5650 100644 --- a/src/dr_mp3.h +++ b/src/dr_mp3.h @@ -4192,7 +4192,7 @@ static float* drmp3__full_read_and_close_f32(drmp3* pMP3, drmp3_config* pConfig, oldFramesBufferSize = framesCapacity * pMP3->channels * sizeof(float); newFramesBufferSize = newFramesCap * pMP3->channels * sizeof(float); - if (newFramesBufferSize > DRMP3_SIZE_MAX) { + if (newFramesBufferSize > (drmp3_uint64)DRMP3_SIZE_MAX) { break; } @@ -4260,7 +4260,7 @@ static drmp3_int16* drmp3__full_read_and_close_s16(drmp3* pMP3, drmp3_config* pC oldFramesBufferSize = framesCapacity * pMP3->channels * sizeof(drmp3_int16); newFramesBufferSize = newFramesCap * pMP3->channels * sizeof(drmp3_int16); - if (newFramesBufferSize > DRMP3_SIZE_MAX) { + if (newFramesBufferSize > (drmp3_uint64)DRMP3_SIZE_MAX) { break; } From 01243956c0fec8c27ddfdf5d0706bb742e8838d0 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Mon, 7 Jun 2021 23:55:50 +0300 Subject: [PATCH 025/606] minor build fixes. --- src/SDL12_compat.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 991213871..be51cefbc 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -6036,7 +6036,7 @@ StartCDAudioPlaying(SDL12_CD *cdrom, const int start_track, const int start_fram { drmp3 mp3; const SDL_bool loaded = LoadCDTrack(start_track, &mp3); - const SDL_bool seeking = loaded && (start_frame > 0); + const SDL_bool seeking = (loaded && (start_frame > 0))? SDL_TRUE : SDL_FALSE; const drmp3_uint64 pcm_frame = seeking ? ((drmp3_uint64) ((start_frame / 75.0) * mp3.sampleRate)) : 0; if (seeking) { /* do seeking before handing off to the audio thread. */ @@ -6305,7 +6305,7 @@ FakeCdRomAudioCallback(AudioCallbackWrapperData *data, Uint8 *stream, int len, c } if ((total_available == 0) && (data->cdrom_mp3.atEnd)) { /* mp3 is done for whatever reason */ - SDL_bool silence = ((!must_mix) && (available < len)); /* silence any section we couldn't provide */ + SDL_bool silence = ((!must_mix) && (available < len))? SDL_TRUE : SDL_FALSE; /* silence any section we couldn't provide */ FreeMp3(&data->cdrom_mp3); From 6fcdfa5103c131a19d4ce06bc062fe88ace80b14 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Mon, 7 Jun 2021 23:55:50 +0300 Subject: [PATCH 026/606] add missing newline at end of LICENSE.txt --- LICENSE.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/LICENSE.txt b/LICENSE.txt index 579141f03..04694607b 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,5 +1,5 @@ Copyright (C) 1997-2021 Sam Lantinga - + This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. @@ -7,7 +7,7 @@ arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: - + 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be @@ -19,4 +19,4 @@ freely, subject to the following restrictions: This project includes code from dr_mp3 ( https://github.com/mackron/dr_libs ) -which can be treated as public domain or MIT-0 licensed, at your option. \ No newline at end of file +which can be treated as public domain or MIT-0 licensed, at your option. From 1eb90cbab9d1f551be642933f1f5d23e7b5cabba Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Fri, 4 Jun 2021 00:37:50 +0200 Subject: [PATCH 027/606] cmake: Fix OpenGL linking This fixes building on Linux with libOpenGL (GLVND-specific) instead of libGL (legacy, GLX-specific) --- CMakeLists.txt | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2231d1a10..76f3b3e35 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -141,13 +141,20 @@ if(SDL12TESTS) test_program(threadwin "test/threadwin.c") test_program(torturethread "test/torturethread.c") + if(WIN32) + target_link_libraries(testgl "OpenGL32") + else() + find_package(OpenGL COMPONENTS OpenGL REQUIRED) + + if(CMAKE_VERSION VERSION_LESS 3.10) + target_link_libraries(testgl ${OPENGL_gl_LIBRARY}) + else() + target_link_libraries(testgl ${OPENGL_opengl_LIBRARY}) + endif() + endif() + if(APPLE) - target_link_libraries(testgl "-framework OpenGL") set_target_properties(testgl PROPERTIES COMPILE_DEFINITIONS "GL_SILENCE_DEPRECATION=1") - elseif(WIN32) - target_link_libraries(testgl "OpenGL32") - else() - target_link_libraries(testgl "GL") endif() foreach(fname "icon.bmp" "moose.dat" "picture.xbm" "sail.bmp" "sample.bmp" "sample.wav" "utf8.txt") From b8eb1765c7b06b4de248d56691b3c9cf17d17e98 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 7 Jun 2021 19:27:29 -0400 Subject: [PATCH 028/606] dr_mp3: Remove the "decode whole MP3 at once" functions, as we only stream. --- src/SDL12_compat.c | 1 + src/dr_mp3.h | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index be51cefbc..46bd4c0eb 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -5694,6 +5694,7 @@ SDL_LoadWAV_RW(SDL12_RWops *rwops12, int freerwops12, #define DR_MP3_NO_STDIO 1 #define DR_MP3_NO_S16 1 #define DR_MP3_FLOAT_OUTPUT 1 +#define DR_MP3_NO_FULL_READ 1 #define DRMP3_ASSERT(x) SDL_assert((x)) #define DRMP3_MALLOC(sz) SDL20_malloc((sz)) #define DRMP3_REALLOC(p, sz) SDL20_realloc((p), (sz)) diff --git a/src/dr_mp3.h b/src/dr_mp3.h index c280a5650..8f86054b4 100644 --- a/src/dr_mp3.h +++ b/src/dr_mp3.h @@ -483,6 +483,7 @@ Use drmp3_calculate_seek_points() to calculate the seek points. DRMP3_API drmp3_bool32 drmp3_bind_seek_table(drmp3* pMP3, drmp3_uint32 seekPointCount, drmp3_seek_point* pSeekPoints); +#ifndef DR_MP3_NO_FULL_READ /* Opens an decodes an entire MP3 stream as a single operation. @@ -506,6 +507,7 @@ DRMP3_API float* drmp3_open_file_and_read_pcm_frames_f32(const char* filePath, d DRMP3_API drmp3_int16* drmp3_open_file_and_read_pcm_frames_s16(const char* filePath, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks); #endif #endif +#endif /* Allocates a block of memory on the heap. @@ -4161,7 +4163,7 @@ DRMP3_API drmp3_bool32 drmp3_bind_seek_table(drmp3* pMP3, drmp3_uint32 seekPoint return DRMP3_TRUE; } - +#ifndef DR_MP3_NO_FULL_READ static float* drmp3__full_read_and_close_f32(drmp3* pMP3, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount) { drmp3_uint64 totalFramesRead = 0; @@ -4365,6 +4367,7 @@ DRMP3_API drmp3_int16* drmp3_open_file_and_read_pcm_frames_s16(const char* fileP } #endif #endif +#endif DRMP3_API void* drmp3_malloc(size_t sz, const drmp3_allocation_callbacks* pAllocationCallbacks) { From 1e301dd87c07fd1b97d358db6b85360d0720f2e9 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 7 Jun 2021 19:53:06 -0400 Subject: [PATCH 029/606] dr_mp3: disable another sint16-specific function. --- src/dr_mp3.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/dr_mp3.h b/src/dr_mp3.h index 8f86054b4..20f25c261 100644 --- a/src/dr_mp3.h +++ b/src/dr_mp3.h @@ -3693,6 +3693,7 @@ DRMP3_API drmp3_uint64 drmp3_read_pcm_frames_f32(drmp3* pMP3, drmp3_uint64 frame #endif } +#ifndef DR_MP3_NO_S16 DRMP3_API drmp3_uint64 drmp3_read_pcm_frames_s16(drmp3* pMP3, drmp3_uint64 framesToRead, drmp3_int16* pBufferOut) { if (pMP3 == NULL || pMP3->onRead == NULL) { @@ -3729,6 +3730,7 @@ DRMP3_API drmp3_uint64 drmp3_read_pcm_frames_s16(drmp3* pMP3, drmp3_uint64 frame } #endif } +#endif static void drmp3_reset(drmp3* pMP3) { From e43bfcc7616435482a2455c003dd29feda6aa3bf Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 7 Jun 2021 20:47:45 -0400 Subject: [PATCH 030/606] dr_mp3: chop out more sint16 functions. --- src/dr_mp3.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/dr_mp3.h b/src/dr_mp3.h index 20f25c261..9e61bdfa6 100644 --- a/src/dr_mp3.h +++ b/src/dr_mp3.h @@ -3551,6 +3551,7 @@ DRMP3_API void drmp3_uninit(drmp3* pMP3) drmp3__free_from_callbacks(pMP3->pData, &pMP3->allocationCallbacks); } +#ifndef DR_MP3_NO_S16 #if defined(DR_MP3_FLOAT_OUTPUT) static void drmp3_f32_to_s16(drmp3_int16* dst, const float* src, drmp3_uint64 sampleCount) { @@ -3607,6 +3608,7 @@ static void drmp3_s16_to_f32(float* dst, const drmp3_int16* src, drmp3_uint64 sa } } #endif +#endif static drmp3_uint64 drmp3_read_pcm_frames_raw(drmp3* pMP3, drmp3_uint64 framesToRead, void* pBufferOut) { From bbebe7c50edc7b664fa77d4c1fa738708df5fbc3 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 7 Jun 2021 20:41:03 -0400 Subject: [PATCH 031/606] Don't allocate a drmp3 on the stack; it's like 16 kilobytes! --- src/SDL12_compat.c | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 46bd4c0eb..d3431d8d3 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -5866,6 +5866,7 @@ SDL_CDOpen(int drive) SDL12_CD *retval; size_t alloclen; char *fullpath; + drmp3 *mp3 = NULL; Uint32 total_track_offset = 0; if (!ValidCDDriveIndex(drive)) { @@ -5886,6 +5887,14 @@ SDL_CDOpen(int drive) return NULL; } + mp3 = (drmp3 *) SDL20_malloc(sizeof (drmp3)); + if (!mp3) { + SDL20_free(fullpath); + SDL20_free(retval); + SDL20_OutOfMemory(); + return NULL; + } + /* We should probably do a proper enumeration of this directory, but that needs platform-specific code that SDL2 doesn't offer. readdir() is surprisingly hard to do without a bunch of different @@ -5894,7 +5903,6 @@ SDL_CDOpen(int drive) FIXME("Can we do something more robust than this for directory enumeration?"); for (;;) { SDL_RWops *rw; - drmp3 mp3; drmp3_uint64 pcmframes; drmp3_uint32 samplerate; SDL12_CDtrack *track; @@ -5907,14 +5915,14 @@ SDL_CDOpen(int drive) break; /* ok, we're done looking for more. */ } - if (!drmp3_init(&mp3, mp3_sdlrwops_read, mp3_sdlrwops_seek, rw, NULL)) { + if (!drmp3_init(mp3, mp3_sdlrwops_read, mp3_sdlrwops_seek, rw, NULL)) { SDL20_RWclose(rw); break; /* ok, we're done looking for more. */ } - pcmframes = drmp3_get_pcm_frame_count(&mp3); - samplerate = mp3.sampleRate; - FreeMp3(&mp3); + pcmframes = drmp3_get_pcm_frame_count(mp3); + samplerate = mp3->sampleRate; + FreeMp3(mp3); track = &retval->track[retval->numtracks]; track->id = retval->numtracks; @@ -5929,6 +5937,7 @@ SDL_CDOpen(int drive) break; /* max tracks you can have on an audio CD. */ } } + SDL20_free(mp3); SDL20_free(fullpath); retval->id = 1; /* just to be non-zero, I guess. */ @@ -6035,13 +6044,17 @@ LoadCDTrack(const int tracknum, drmp3 *mp3) static int StartCDAudioPlaying(SDL12_CD *cdrom, const int start_track, const int start_frame, const int ntracks, const int nframes) { - drmp3 mp3; - const SDL_bool loaded = LoadCDTrack(start_track, &mp3); + drmp3 *mp3 = (drmp3 *) SDL20_malloc(sizeof (drmp3)); + const SDL_bool loaded = mp3 ? LoadCDTrack(start_track, mp3) : SDL_FALSE; const SDL_bool seeking = (loaded && (start_frame > 0))? SDL_TRUE : SDL_FALSE; - const drmp3_uint64 pcm_frame = seeking ? ((drmp3_uint64) ((start_frame / 75.0) * mp3.sampleRate)) : 0; + const drmp3_uint64 pcm_frame = seeking ? ((drmp3_uint64) ((start_frame / 75.0) * mp3->sampleRate)) : 0; + + if (!mp3) { + return SDL20_OutOfMemory(); + } if (seeking) { /* do seeking before handing off to the audio thread. */ - drmp3_seek_to_pcm_frame(&mp3, pcm_frame); + drmp3_seek_to_pcm_frame(mp3, pcm_frame); } SDL20_LockAudio(); @@ -6054,11 +6067,13 @@ StartCDAudioPlaying(SDL12_CD *cdrom, const int start_track, const int start_fram audio_cbdata->cdrom_stop_nframes = nframes; FreeMp3(&audio_cbdata->cdrom_mp3); if (loaded) { - SDL20_memcpy(&audio_cbdata->cdrom_mp3, &mp3, sizeof (drmp3)); + SDL20_memcpy(&audio_cbdata->cdrom_mp3, mp3, sizeof (drmp3)); } } SDL20_UnlockAudio(); + SDL20_free(mp3); + return loaded ? 0 : SDL20_SetError("Failed to start CD track"); } From 912ef3fc6dc83d52901bb377cb80703df758c9ef Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 7 Jun 2021 22:37:12 -0400 Subject: [PATCH 032/606] Fixing some MSVC compiler warnings. --- src/SDL12_compat.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index d3431d8d3..574216eaf 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -2005,8 +2005,8 @@ AdjustOpenGLLogicalScalingPoint(int *x, int *y) scale_x = (float)OpenGLLogicalScalingWidth / viewport.w; scale_y = (float)OpenGLLogicalScalingHeight / viewport.h; - adjusted_x = (*x - viewport.x) * scale_x; - adjusted_y = (*y - viewport.y) * scale_y; + adjusted_x = (int) ((*x - viewport.x) * scale_x); + adjusted_y = (int) ((*y - viewport.y) * scale_y); /* Clamp the result to the visible window */ *x = SDL_max(SDL_min(adjusted_x, OpenGLLogicalScalingWidth), 0); @@ -6087,11 +6087,11 @@ SDL_CDPlayTracks(SDL12_CD *cdrom, int start_track, int start_frame, int ntracks, return SDL20_SetError("Tray empty"); } else if ((start_track < 0) || (start_track >= cdrom->numtracks)) { return SDL20_SetError("Invalid start track"); - } else if ((start_frame < 0) || (start_frame >= cdrom->track[start_track].length)) { + } else if ((start_frame < 0) || (((Uint32) start_frame) >= cdrom->track[start_track].length)) { return SDL20_SetError("Invalid start frame"); } else if ((ntracks < 0) || ((start_track + ntracks) >= cdrom->numtracks)) { return SDL20_SetError("Invalid number of tracks"); - } else if ((nframes < 0) || (nframes >= cdrom->track[start_track + ntracks].length)) { + } else if ((nframes < 0) || (((Uint32) nframes) >= cdrom->track[start_track + ntracks].length)) { return SDL20_SetError("Invalid number of frames"); } @@ -6106,7 +6106,8 @@ SDL_CDPlayTracks(SDL12_CD *cdrom, int start_track, int start_frame, int ntracks, DECLSPEC int SDLCALL SDL_CDPlay(SDL12_CD *cdrom, int start, int length) { - int remain = length; + const Uint32 ui32start = (Uint32) start; + Uint32 remain = (Uint32) length; int start_track = -1; int start_frame = -1; int ntracks = -1; @@ -6117,10 +6118,14 @@ SDL_CDPlay(SDL12_CD *cdrom, int start, int length) return -1; } else if (cdrom->status == SDL12_CD_TRAYEMPTY) { return SDL20_SetError("Tray empty"); + } else if (start < 0) { + return SDL20_SetError("Invalid start"); + } else if (length < 0) { + return SDL20_SetError("Invalid length"); } for (i = 0; i < cdrom->numtracks; i++) { - if ((start >= cdrom->track[i].offset) && (start < (cdrom->track[i].offset + cdrom->track[i].length))) { + if ((ui32start >= cdrom->track[i].offset) && (ui32start < (cdrom->track[i].offset + cdrom->track[i].length))) { start_track = i; break; } From 02ff6fe0883a65807fee6b7cea57e1a812bb96fd Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 7 Jun 2021 23:09:58 -0400 Subject: [PATCH 033/606] Fixed more MSVC compiler warnings. --- src/SDL12_compat.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 574216eaf..f39d890ed 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -6303,9 +6303,9 @@ FakeCdRomAudioCallback(AudioCallbackWrapperData *data, Uint8 *stream, int len, c } total_available = SDL20_AudioStreamAvailable(data->cdrom_stream); - available = (len < total_available) ? len : total_available; - if (len < available) { - available = len; + available = total_available; + if (((Uint32) len) < available) { + available = (Uint32) len; } if (available > 0) { @@ -6316,7 +6316,7 @@ FakeCdRomAudioCallback(AudioCallbackWrapperData *data, Uint8 *stream, int len, c SDL20_MixAudio(stream, data->mix_buffer, available, SDL_MIX_MAXVOLUME); } - data->cdrom_pcm_frames_written += (available / ((double) SDL_AUDIO_BITSIZE(data->device_format.format) / 8.0)) / data->device_format.channels; + data->cdrom_pcm_frames_written += (int) ((available / ((double) SDL_AUDIO_BITSIZE(data->device_format.format) / 8.0)) / data->device_format.channels); data->cdrom_cur_frame = (int) ((((double)data->cdrom_pcm_frames_written) / ((double)data->device_format.freq)) * CDAUDIO_FPS); if (data->cdrom_stop_ntracks == 0) { if (data->cdrom_cur_frame >= data->cdrom_stop_nframes) { @@ -6326,7 +6326,7 @@ FakeCdRomAudioCallback(AudioCallbackWrapperData *data, Uint8 *stream, int len, c } if ((total_available == 0) && (data->cdrom_mp3.atEnd)) { /* mp3 is done for whatever reason */ - SDL_bool silence = ((!must_mix) && (available < len))? SDL_TRUE : SDL_FALSE; /* silence any section we couldn't provide */ + SDL_bool silence = ((!must_mix) && (available < ((Uint32) len))) ? SDL_TRUE : SDL_FALSE; /* silence any section we couldn't provide */ FreeMp3(&data->cdrom_mp3); @@ -6340,7 +6340,7 @@ FakeCdRomAudioCallback(AudioCallbackWrapperData *data, Uint8 *stream, int len, c if (!loaded) { data->cdrom_status = SDL12_CD_TRAYEMPTY; FIXME("Maybe just mark it stopped?"); } else { /* let new track fill out rest of callback. */ - if (available < len) { + if (available < ((Uint32) len)) { FakeCdRomAudioCallback(data, stream + available, len - available, must_mix); silence = SDL_FALSE; } From fd56c5bdc88cc709e95ac0e781d0023587000b56 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Tue, 8 Jun 2021 06:23:28 +0300 Subject: [PATCH 034/606] Makefile.mingw: link to libgcc. fixes linkage of x86 builds. See: https://github.com/libsdl-org/sdl12-compat/issues/32#issuecomment-856263791 (CMake would need the same adjustment.) --- src/Makefile.mingw | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 085ffcbff..b31e890c6 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -18,6 +18,7 @@ CPPFLAGS = -DDLL_EXPORT -DNDEBUG CFLAGS = -O3 -Wall LDFLAGS = -nostdlib -shared -Wl,--no-undefined -Wl,--enable-auto-image-base -Wl,--out-implib,$(LIB) LDLIBS = -lkernel32 -luser32 +LDLIBS += -static-libgcc -lgcc LIB = libSDL.dll.a DLL = SDL.dll From a8891baae62812d66d6db3ec03bcf292dd3c9dd5 Mon Sep 17 00:00:00 2001 From: David Gow Date: Tue, 8 Jun 2021 17:36:48 +0800 Subject: [PATCH 035/606] testoverlay: Remove unused 'flip' variable. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The testoverlay SDL 1.2 test program has a variable 'flip' which is never used. It seems to be intended to be used for double-buffering/page flipping, but it's never read from after it's set. This results in a warning being printed on gcc 10.3: /home/david/Development/sdl12-compat/test/testoverlay.c: In function ‘main’: /home/david/Development/sdl12-compat/test/testoverlay.c:324:6: warning: variable ‘flip’ set but not used [-Wunused-but-set-variable] --- test/testoverlay.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/test/testoverlay.c b/test/testoverlay.c index 823e45331..b06d0fe0f 100644 --- a/test/testoverlay.c +++ b/test/testoverlay.c @@ -321,7 +321,6 @@ static void PrintUsage(char *argv0) int main(int argc, char **argv) { char *argv0 = argv[0]; - int flip; int delay; int desired_bpp; Uint32 video_flags, overlay_format; @@ -332,7 +331,6 @@ int main(int argc, char **argv) int i; /* Set default options and check command-line */ - flip = 0; scale=0; monochrome=0; luminance=100; @@ -473,7 +471,6 @@ int main(int argc, char **argv) (screen->flags&SDL_HWSURFACE) ? "video" : "system"); if ( screen->flags & SDL_DOUBLEBUF ) { printf("Double-buffering enabled\n"); - flip = 1; } /* Set the window manager title bar */ From d7ce2ec90fc2482c3e60c1c84bc59c864805450c Mon Sep 17 00:00:00 2001 From: David Gow Date: Tue, 8 Jun 2021 17:40:19 +0800 Subject: [PATCH 036/606] testloadso: Actually return an error if one occurs The 'retval' value used to track what exit code the test app should return is never actually used. Instead 0 (success) is returned unconditionally, which can cause the program to appear as though it succeded (at least to a script which doesn't check the text output). This was caught by an unusued variable warning in gcc, and appears to be an actual bug, rather than just a useless variable. --- test/testloadso.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/testloadso.c b/test/testloadso.c index 39c14c69f..802a50814 100644 --- a/test/testloadso.c +++ b/test/testloadso.c @@ -65,7 +65,7 @@ int main(int argc, char *argv[]) SDL_UnloadObject(lib); } SDL_Quit(); - return(0); + return retval; } From 5f2bbe7b414d5ff7d8a9d004d3c631068815ba23 Mon Sep 17 00:00:00 2001 From: David Gow Date: Tue, 8 Jun 2021 16:09:14 +0800 Subject: [PATCH 037/606] Add rudimentary emulation of SDL 1.2 scancodes Introduce a new Scancode20to12() function to convert an SDL 2.0 scancode into an SDL 1.2 scancode. The actual conversion is platform specific, because the SDL 1.2 scancodes vary wildly between different platforms (and, potentially, different configuations or hardware on the same platform). The CASESCANCODE20TO12() macro has an idealised 'Linux' scancode (which is transformed to get the windows scancode), and a separate Mac OS X scancode. Some scancodes on Linux are deliberately missing (set to 0), as they differ between Linux configurations, and applications (*cough DOSBox *cough*) query the system config to work out the values for those keys. Using 0 triggers a fallback to the keysyms, which work fine. This is horribly ugly, but that appropriately reflects the horrible ugliness of how SDL 1.2 scancodes are used. --- src/SDL12_compat.c | 140 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 136 insertions(+), 4 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index f39d890ed..0b9e7e76c 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -2380,6 +2380,140 @@ Keysym20to12(const SDL_Keycode keysym20) return SDLK12_UNKNOWN; } +static Uint8 +Scancode20to12(SDL_Scancode sc) +{ + /* SDL 1.2 scancodes are the actual raw scancodes (for the most part), and + so differ wildly between different systems. Fortunately, this means + they're rarely used, and often have fallbacks. Here, we support them + for three systems: Win32, Mac OS X, and a synthesized pseudo-Linux that + should work. + Windows scancodes are bascially just Linux ones - 8. OS X has a totally + different set of scancodes from everyone else. Linux's scancodes change + depending on what driver you're using, but only really for a few keys. + Since there are applications (DOSBox) which look this up and behave + accordingly, but have fallbacks, those keys have scancodes of 0 here, + to trigger the fallbacks. */ + switch(sc) { +#if defined(_WIN32) +#define CASESCANCODE20TO12(sc20, sc12, sc12mac) case SDL_SCANCODE_##sc20: return (sc12 ? (sc12 - 8) : 0) +#elif defined(__MACOSX__) +#define CASESCANCODE20TO12(sc20, sc12, sc12mac) case SDL_SCANCODE_##sc20: return sc12mac +#else +#define CASESCANCODE20TO12(sc20, sc12, sc12mac) case SDL_SCANCODE_##sc20: return sc12 +#endif + CASESCANCODE20TO12(0, 0x13, 0x1D); + CASESCANCODE20TO12(1, 0x0A, 0x12); + CASESCANCODE20TO12(2, 0x0B, 0x13); + CASESCANCODE20TO12(3, 0x0C, 0x14); + CASESCANCODE20TO12(4, 0x0D, 0x15); + CASESCANCODE20TO12(5, 0x0E, 0x17); + CASESCANCODE20TO12(6, 0x0F, 0x16); + CASESCANCODE20TO12(7, 0x10, 0x1A); + CASESCANCODE20TO12(8, 0x11, 0x1C); + CASESCANCODE20TO12(9, 0x12, 0x19); + CASESCANCODE20TO12(A, 0x26, 0x19); + CASESCANCODE20TO12(APOSTROPHE, 0x30, 0x27); + CASESCANCODE20TO12(B, 0x38, 0x0B); + CASESCANCODE20TO12(BACKSLASH, 0x33, 0x2A); + CASESCANCODE20TO12(BACKSPACE, 0x16, 0x33); + CASESCANCODE20TO12(C, 0x36, 0x08); + CASESCANCODE20TO12(CAPSLOCK, 0x42, 0x39); + CASESCANCODE20TO12(COMMA, 0x3B, 0x2B); + CASESCANCODE20TO12(D, 0x28, 0x02); + CASESCANCODE20TO12(DELETE, 0x00, 0x75); + CASESCANCODE20TO12(DOWN, 0x00, 0x7D); + CASESCANCODE20TO12(E, 0x1A, 0x0E); + CASESCANCODE20TO12(END, 0x00, 0x77); + CASESCANCODE20TO12(EQUALS, 0x15, 0x18); + CASESCANCODE20TO12(ESCAPE, 0x09, 0x35); + CASESCANCODE20TO12(F, 0x29, 0x03); + CASESCANCODE20TO12(F1, 0x43, 0x7A); + CASESCANCODE20TO12(F10, 0x4C, 0x6E); + CASESCANCODE20TO12(F11, 0x5F, 0x67); + CASESCANCODE20TO12(F12, 0x60, 0x6F); + CASESCANCODE20TO12(F2, 0x44, 0x78); + CASESCANCODE20TO12(F3, 0x45, 0x63); + CASESCANCODE20TO12(F4, 0x46, 0x76); + CASESCANCODE20TO12(F5, 0x47, 0x60); + CASESCANCODE20TO12(F6, 0x48, 0x61); + CASESCANCODE20TO12(F7, 0x49, 0x62); + CASESCANCODE20TO12(F8, 0x4A, 0x64); + CASESCANCODE20TO12(F9, 0x4B, 0x65); + CASESCANCODE20TO12(G, 0x2A, 0x05); + CASESCANCODE20TO12(GRAVE, 0x31, 0x32); + CASESCANCODE20TO12(H, 0x2B, 0x04); + CASESCANCODE20TO12(HOME, 0x00, 0x73); + CASESCANCODE20TO12(I, 0x1F, 0x22); + CASESCANCODE20TO12(INSERT, 0x00, 0x72); + CASESCANCODE20TO12(J, 0x2C, 0x26); + CASESCANCODE20TO12(K, 0x2D, 0x28); + CASESCANCODE20TO12(KP_0, 0x5A, 0x52); + CASESCANCODE20TO12(KP_1, 0x57, 0x53); + CASESCANCODE20TO12(KP_2, 0x58, 0x54); + CASESCANCODE20TO12(KP_3, 0x59, 0x55); + CASESCANCODE20TO12(KP_4, 0x53, 0x56); + CASESCANCODE20TO12(KP_5, 0x54, 0x57); + CASESCANCODE20TO12(KP_6, 0x55, 0x58); + CASESCANCODE20TO12(KP_7, 0x4F, 0x59); + CASESCANCODE20TO12(KP_8, 0x50, 0x5B); + CASESCANCODE20TO12(KP_9, 0x51, 0x5C); + CASESCANCODE20TO12(KP_DIVIDE, 0x00, 0x4B); + CASESCANCODE20TO12(KP_ENTER, 0x00, 0x4C); + CASESCANCODE20TO12(KP_EQUALS, 0x00, 0x51); + CASESCANCODE20TO12(KP_MINUS, 0x52, 0x4E); + CASESCANCODE20TO12(KP_MULTIPLY, 0x3F, 0x42); + CASESCANCODE20TO12(KP_PERIOD, 0x5B, 0x41); + CASESCANCODE20TO12(KP_PLUS, 0x56, 0x44); + CASESCANCODE20TO12(L, 0x2E, 0x25); + CASESCANCODE20TO12(LALT, 0x40, 0x3A); + CASESCANCODE20TO12(LCTRL, 0x25, 0x4B); + CASESCANCODE20TO12(LEFT, 0x00, 0x7B); + CASESCANCODE20TO12(LEFTBRACKET, 0x22, 0x21); + CASESCANCODE20TO12(LGUI, 0x85, 0x37); + CASESCANCODE20TO12(LSHIFT, 0x32, 0x38); + CASESCANCODE20TO12(M, 0x3A, 0x29); + CASESCANCODE20TO12(MINUS, 0x14, 0x1B); + CASESCANCODE20TO12(N, 0x39, 0x28); + CASESCANCODE20TO12(NUMLOCKCLEAR, 0x4D, 0x47); + CASESCANCODE20TO12(O, 0x20, 0x1F); + CASESCANCODE20TO12(P, 0x21, 0x23); + CASESCANCODE20TO12(PAGEDOWN, 0x00, 0x79); + CASESCANCODE20TO12(PAGEUP, 0x00, 0x74); + CASESCANCODE20TO12(PERIOD, 0x3C, 0x2F); + CASESCANCODE20TO12(PRINTSCREEN, 0x6B, 0x6B); + CASESCANCODE20TO12(Q, 0x18, 0x0C); + CASESCANCODE20TO12(R, 0x1B, 0x0F); + CASESCANCODE20TO12(RETURN, 0x24, 0x24); + CASESCANCODE20TO12(RIGHT, 0x00, 0x7C); + CASESCANCODE20TO12(RIGHTBRACKET, 0x23, 0x1E); + CASESCANCODE20TO12(S, 0x27, 0x01); + CASESCANCODE20TO12(SCROLLLOCK, 0x4E, 0x71); + CASESCANCODE20TO12(SEMICOLON, 0x2F, 0x29); + CASESCANCODE20TO12(SLASH, 0x3D, 0x2C); + CASESCANCODE20TO12(SPACE, 0x41, 0x31); + CASESCANCODE20TO12(T, 0x1C, 0x11); + CASESCANCODE20TO12(TAB, 0x17, 0x30); + CASESCANCODE20TO12(U, 0x00, 0x20); + CASESCANCODE20TO12(UP, 0x00, 0x7E); + CASESCANCODE20TO12(V, 0x37, 0x09); + CASESCANCODE20TO12(W, 0x19, 0x0D); + CASESCANCODE20TO12(X, 0x35, 0x07); + CASESCANCODE20TO12(Y, 0x1D, 0x10); + CASESCANCODE20TO12(Z, 0x34, 0x06); +#undef CASESCANCODE20TO12 + default: + /* If we don't know it, return 0, which is "unknown" on everything + except Mac OS X, where it's "A" for whatever reason. */ +#ifdef __MACOSX__ + return 0x34; /* DOSBox should treat this as unknown. */ +#else + return 0; +#endif + } + return 0; +} + DECLSPEC Uint8 * SDLCALL SDL_GetKeyState(int *numkeys) { @@ -2522,9 +2656,8 @@ EventFilter20to12(void *data, SDL_Event *event20) event12.type = (event20->type == SDL_KEYDOWN) ? SDL12_KEYDOWN : SDL12_KEYUP; event12.key.which = 0; event12.key.state = event20->key.state; - FIXME("SDL1.2 and SDL2.0 scancodes are incompatible"); /* turns out that some apps actually made use of the hardware scancodes (checking for platform beforehand) */ - event12.key.keysym.scancode = 0; + event12.key.keysym.scancode = Scancode20to12(event20->key.keysym.scancode); event12.key.keysym.mod = event20->key.keysym.mod; /* these match up between 1.2 and 2.0! */ event12.key.keysym.unicode = 0; @@ -2548,9 +2681,8 @@ EventFilter20to12(void *data, SDL_Event *event20) PendingKeydownEvent.type = (event20->type == SDL_KEYDOWN) ? SDL12_KEYDOWN : SDL12_KEYUP; PendingKeydownEvent.key.which = 0; PendingKeydownEvent.key.state = event20->key.state; - FIXME("SDL1.2 and SDL2.0 scancodes are incompatible"); /* turns out that some apps actually made use of the hardware scancodes (checking for platform beforehand) */ - PendingKeydownEvent.key.keysym.scancode = 0; + PendingKeydownEvent.key.keysym.scancode = Scancode20to12(event20->key.keysym.scancode); PendingKeydownEvent.key.keysym.mod = event20->key.keysym.mod; /* these match up between 1.2 and 2.0! */ PendingKeydownEvent.key.keysym.unicode = 0; From 01e0b59b4662b9b840db143c735e4320904baa9e Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Fri, 4 Jun 2021 00:07:04 +0200 Subject: [PATCH 038/606] sdl-config.in,sdl12_compat.pc.in: sync and use CMake variables --- CMakeLists.txt | 18 ++++++------------ sdl-config.in | 13 +++++++------ sdl12_compat.pc.in | 8 ++++---- 3 files changed, 17 insertions(+), 22 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 76f3b3e35..ceebd3af5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -167,6 +167,12 @@ install(TARGETS SDL ) if(SDL12DEVEL) + set(SDL_VERSION "${SDL12_COMPAT_VERSION_STR}") + set(SDL_CFLAGS "-D_GNU_SOURCE=1 -D_REENTRANT") + set(SDL_RLD_FLAGS "") # !!! FIXME: this forces rpath, which we might want? + set(SDL_LIBS "-lSDL") + set(SDL_STATIC_LIBS "-lm -ldl -lpthread") + install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} ) configure_file(sdl12_compat.pc.in sdl12_compat.pc @ONLY) @@ -174,24 +180,12 @@ if(SDL12DEVEL) DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig ) - # !!! FIXME: lots of these sdl-config vars probably need more customization. - # !!! FIXME: do we _want_ static builds? set(ENABLE_STATIC_TRUE "") set(ENABLE_STATIC_FALSE "#") set(ENABLE_SHARED_TRUE "") set(ENABLE_SHARED_FALSE "#") - set(SDL_VERSION "${SDL12_COMPAT_VERSION_STR}") - set(SDL_CFLAGS "-D_GNU_SOURCE=1 -D_REENTRANT") - set(SDL_RLD_FLAGS "") # !!! FIXME: this forces rpath, which we might want? - set(SDL_LIBS "-lSDL") - set(SDL_STATIC_LIBS "-lm -ldl -lpthread") - set(prefix ${CMAKE_INSTALL_PREFIX}) - set(exec_prefix "\${prefix}") - set(libdir "\${exec_prefix}/lib${LIB_SUFFIX}") - set(bindir "\${exec_prefix}/bin") - set(includedir "\${prefix}/include") configure_file("${CMAKE_SOURCE_DIR}/sdl-config.in" "${CMAKE_BINARY_DIR}/sdl-config" @ONLY) install(PROGRAMS "${CMAKE_BINARY_DIR}/sdl-config" DESTINATION bin) endif() diff --git a/sdl-config.in b/sdl-config.in index f7895c22f..528a355ee 100755 --- a/sdl-config.in +++ b/sdl-config.in @@ -7,10 +7,11 @@ # Copied and modified from SDL2's sdl2-compat. -prefix=@prefix@ -exec_prefix=@exec_prefix@ +prefix=@CMAKE_INSTALL_PREFIX@ +exec_prefix=${prefix} exec_prefix_set=no -libdir=@libdir@ +libdir=@CMAKE_INSTALL_FULL_LIBDIR@ +includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@ @ENABLE_STATIC_FALSE@usage="\ @ENABLE_STATIC_FALSE@Usage: $0 [--prefix[=DIR]] [--exec-prefix[=DIR]] [--version] [--cflags] [--libs]" @@ -49,14 +50,14 @@ while test $# -gt 0; do echo @SDL_VERSION@ ;; --cflags) - echo -I@includedir@/SDL2 @SDL_CFLAGS@ + echo -I${includedir}/SDL @SDL_CFLAGS@ ;; @ENABLE_SHARED_TRUE@ --libs) -@ENABLE_SHARED_TRUE@ echo -L@libdir@ @SDL_RLD_FLAGS@ @SDL_LIBS@ +@ENABLE_SHARED_TRUE@ echo -L${libdir} @SDL_RLD_FLAGS@ @SDL_LIBS@ @ENABLE_SHARED_TRUE@ ;; @ENABLE_STATIC_TRUE@@ENABLE_SHARED_TRUE@ --static-libs) @ENABLE_STATIC_TRUE@@ENABLE_SHARED_FALSE@ --libs|--static-libs) -@ENABLE_STATIC_TRUE@ echo -L@libdir@ @SDL_LIBS@ @SDL_STATIC_LIBS@ +@ENABLE_STATIC_TRUE@ echo -L${libdir} @SDL_LIBS@ @SDL_STATIC_LIBS@ @ENABLE_STATIC_TRUE@ ;; *) echo "${usage}" 1>&2 diff --git a/sdl12_compat.pc.in b/sdl12_compat.pc.in index ae32bc01b..39e5c3117 100644 --- a/sdl12_compat.pc.in +++ b/sdl12_compat.pc.in @@ -8,7 +8,7 @@ includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@ Name: sdl12_compat Description: An SDL-1.2 compatibility layer that uses SDL 2.0 behind the scenes. Version: @PROJECT_VERSION@ -Provides: sdl = 1.2.50 -Libs: -L${libdir} -lSDL -lpthread -Libs.private: -lSDL -lpthread -lm -ldl -lpthread -Cflags: -I${includedir}/SDL -D_GNU_SOURCE=1 -D_REENTRANT +Provides: sdl = @SDL_VERSION@ +Libs: -L${libdir} @SDL_RLD_FLAGS@ @SDL_LIBS@ +Libs.private: -L${libdir} @SDL_LIBS@ @SDL_STATIC_LIBS@ +Cflags: -I${includedir}/SDL @SDL_CFLAGS@ From efe97912a54260f3e4c4b2ba5629986adbb9aff7 Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Mon, 7 Jun 2021 02:02:23 +0200 Subject: [PATCH 039/606] cmake: Create symbolic link for -lSDL --- CMakeLists.txt | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index ceebd3af5..4206f9376 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -188,5 +188,15 @@ if(SDL12DEVEL) configure_file("${CMAKE_SOURCE_DIR}/sdl-config.in" "${CMAKE_BINARY_DIR}/sdl-config" @ONLY) install(PROGRAMS "${CMAKE_BINARY_DIR}/sdl-config" DESTINATION bin) + + set(SOEXT ${CMAKE_SHARED_LIBRARY_SUFFIX}) + get_target_property(SONAME SDL OUTPUT_NAME) + if(UNIX AND NOT ANDROID) + install(CODE " + execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink + \"lib${SONAME}${SOPOSTFIX}${SOEXT}\" \"libSDL${SOPOSTFIX}${SOEXT}\" + WORKING_DIRECTORY \"${CMAKE_BINARY_DIR}\")") + install(FILES ${CMAKE_BINARY_DIR}/libSDL${SOPOSTFIX}${SOEXT} DESTINATION "${CMAKE_INSTALL_LIBDIR}") + endif() endif() From a40ab7ba625088d7362c746389e49c9ef81b7bad Mon Sep 17 00:00:00 2001 From: David Gow Date: Wed, 9 Jun 2021 14:33:06 +0800 Subject: [PATCH 040/606] Scancode20to12: Fix missing scancode for 'U' Whoops, this was a copy-paste error on my part: the scancode for 'U' was missing (set to 0x00) for non Mac OS X systems. On keyboard layouts which have 'U' in the same position as US English, the fallback to SDLK_ values hid this issue. The 'U' key should work properly now in things like DOSBox which use scancodes. --- src/SDL12_compat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 0b9e7e76c..dbc64b5fb 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -2494,7 +2494,7 @@ Scancode20to12(SDL_Scancode sc) CASESCANCODE20TO12(SPACE, 0x41, 0x31); CASESCANCODE20TO12(T, 0x1C, 0x11); CASESCANCODE20TO12(TAB, 0x17, 0x30); - CASESCANCODE20TO12(U, 0x00, 0x20); + CASESCANCODE20TO12(U, 0x1E, 0x20); CASESCANCODE20TO12(UP, 0x00, 0x7E); CASESCANCODE20TO12(V, 0x37, 0x09); CASESCANCODE20TO12(W, 0x19, 0x0D); From 429263a90e55ed2c5f86af98a6c3d1bde43c3148 Mon Sep 17 00:00:00 2001 From: David Gow Date: Wed, 9 Jun 2021 14:42:49 +0800 Subject: [PATCH 041/606] Propagate KEY{UP,DOWN} even if keycode is SDLK_UNKNOWN Now that we have scancode and unicode values available, it's worth actually handling keys which might not have an SDLK_ value in SDL 1.2. --- src/SDL12_compat.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index dbc64b5fb..fdc57f086 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -2647,9 +2647,6 @@ EventFilter20to12(void *data, SDL_Event *event20) return 1; /* ignore 2.0-style key repeat events */ } event12.key.keysym.sym = Keysym20to12(event20->key.keysym.sym); - if (event12.key.keysym.sym == SDLK12_UNKNOWN) { - return 1; /* drop it if we can't map it */ - } KeyState[event12.key.keysym.sym] = event20->key.state; @@ -2672,9 +2669,6 @@ EventFilter20to12(void *data, SDL_Event *event20) } PendingKeydownEvent.key.keysym.sym = Keysym20to12(event20->key.keysym.sym); - if (PendingKeydownEvent.key.keysym.sym == SDLK12_UNKNOWN) { - return 1; /* drop it if we can't map it */ - } KeyState[PendingKeydownEvent.key.keysym.sym] = event20->key.state; From 0e48eb26392bab1579f40fdb636cc54ae8154b2a Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Wed, 9 Jun 2021 21:17:29 +0200 Subject: [PATCH 042/606] Add sdl.m4 Copied from SDL-1.2, the equivalent in SDL2 is similar enough that licensing shouldn't be an issue. It is needed to use autoconf on software like smpeg, which has been used to test this. --- CMakeLists.txt | 2 + sdl.m4 | 180 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 182 insertions(+) create mode 100644 sdl.m4 diff --git a/CMakeLists.txt b/CMakeLists.txt index 4206f9376..796dc0b6f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -198,5 +198,7 @@ if(SDL12DEVEL) WORKING_DIRECTORY \"${CMAKE_BINARY_DIR}\")") install(FILES ${CMAKE_BINARY_DIR}/libSDL${SOPOSTFIX}${SOEXT} DESTINATION "${CMAKE_INSTALL_LIBDIR}") endif() + + install(FILES "${CMAKE_SOURCE_DIR}/sdl.m4" DESTINATION "${CMAKE_INSTALL_FULL_DATAROOTDIR}/aclocal") endif() diff --git a/sdl.m4 b/sdl.m4 new file mode 100644 index 000000000..30e1f2144 --- /dev/null +++ b/sdl.m4 @@ -0,0 +1,180 @@ +# Configure paths for SDL +# Sam Lantinga 9/21/99 +# stolen from Manish Singh +# stolen back from Frank Belew +# stolen from Manish Singh +# Shamelessly stolen from Owen Taylor + +# serial 2 + +dnl AM_PATH_SDL([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]]) +dnl Test for SDL, and define SDL_CFLAGS and SDL_LIBS +dnl +AC_DEFUN([AM_PATH_SDL], +[dnl +dnl Get the cflags and libraries from the sdl-config script +dnl +AC_ARG_WITH(sdl-prefix,[ --with-sdl-prefix=PFX Prefix where SDL is installed (optional)], + sdl_prefix="$withval", sdl_prefix="") +AC_ARG_WITH(sdl-exec-prefix,[ --with-sdl-exec-prefix=PFX Exec prefix where SDL is installed (optional)], + sdl_exec_prefix="$withval", sdl_exec_prefix="") +AC_ARG_ENABLE(sdltest, [ --disable-sdltest Do not try to compile and run a test SDL program], + , enable_sdltest=yes) + + min_sdl_version=ifelse([$1], ,1.2.0,$1) + + if test "x$sdl_prefix$sdl_exec_prefix" = x ; then + PKG_CHECK_MODULES([SDL], [sdl >= $min_sdl_version], + [sdl_pc=yes], + [sdl_pc=no]) + else + sdl_pc=no + if test x$sdl_exec_prefix != x ; then + sdl_config_args="$sdl_config_args --exec-prefix=$sdl_exec_prefix" + if test x${SDL_CONFIG+set} != xset ; then + SDL_CONFIG=$sdl_exec_prefix/bin/sdl-config + fi + fi + if test x$sdl_prefix != x ; then + sdl_config_args="$sdl_config_args --prefix=$sdl_prefix" + if test x${SDL_CONFIG+set} != xset ; then + SDL_CONFIG=$sdl_prefix/bin/sdl-config + fi + fi + fi + + if test "x$sdl_pc" = xyes ; then + no_sdl="" + SDL_CONFIG="pkg-config sdl" + else + as_save_PATH="$PATH" + if test "x$prefix" != xNONE && test "$cross_compiling" != yes; then + PATH="$prefix/bin:$prefix/usr/bin:$PATH" + fi + AC_PATH_PROG(SDL_CONFIG, sdl-config, no, [$PATH]) + PATH="$as_save_PATH" + AC_MSG_CHECKING(for SDL - version >= $min_sdl_version) + no_sdl="" + + if test "$SDL_CONFIG" = "no" ; then + no_sdl=yes + else + SDL_CFLAGS=`$SDL_CONFIG $sdl_config_args --cflags` + SDL_LIBS=`$SDL_CONFIG $sdl_config_args --libs` + + sdl_major_version=`$SDL_CONFIG $sdl_config_args --version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` + sdl_minor_version=`$SDL_CONFIG $sdl_config_args --version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` + sdl_micro_version=`$SDL_CONFIG $sdl_config_args --version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` + if test "x$enable_sdltest" = "xyes" ; then + ac_save_CFLAGS="$CFLAGS" + ac_save_CXXFLAGS="$CXXFLAGS" + ac_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $SDL_CFLAGS" + CXXFLAGS="$CXXFLAGS $SDL_CFLAGS" + LIBS="$LIBS $SDL_LIBS" +dnl +dnl Now check if the installed SDL is sufficiently new. (Also sanity +dnl checks the results of sdl-config to some extent +dnl + rm -f conf.sdltest + AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#include +#include +#include "SDL.h" + +int main (int argc, char *argv[]) +{ + int major, minor, micro; + FILE *fp = fopen("conf.sdltest", "w"); + + if (fp) fclose(fp); + + if (sscanf("$min_sdl_version", "%d.%d.%d", &major, &minor, µ) != 3) { + printf("%s, bad version string\n", "$min_sdl_version"); + exit(1); + } + + if (($sdl_major_version > major) || + (($sdl_major_version == major) && ($sdl_minor_version > minor)) || + (($sdl_major_version == major) && ($sdl_minor_version == minor) && ($sdl_micro_version >= micro))) + { + return 0; + } + else + { + printf("\n*** 'sdl-config --version' returned %d.%d.%d, but the minimum version\n", $sdl_major_version, $sdl_minor_version, $sdl_micro_version); + printf("*** of SDL required is %d.%d.%d. If sdl-config is correct, then it is\n", major, minor, micro); + printf("*** best to upgrade to the required version.\n"); + printf("*** If sdl-config was wrong, set the environment variable SDL_CONFIG\n"); + printf("*** to point to the correct copy of sdl-config, and remove the file\n"); + printf("*** config.cache before re-running configure\n"); + return 1; + } +} + +]])], [], [no_sdl=yes], [echo $ac_n "cross compiling; assumed OK... $ac_c"]) + CFLAGS="$ac_save_CFLAGS" + CXXFLAGS="$ac_save_CXXFLAGS" + LIBS="$ac_save_LIBS" + fi + fi + if test "x$no_sdl" = x ; then + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + fi + fi + if test "x$no_sdl" = x ; then + ifelse([$2], , :, [$2]) + else + if test "$SDL_CONFIG" = "no" ; then + echo "*** The sdl-config script installed by SDL could not be found" + echo "*** If SDL was installed in PREFIX, make sure PREFIX/bin is in" + echo "*** your path, or set the SDL_CONFIG environment variable to the" + echo "*** full path to sdl-config." + else + if test -f conf.sdltest ; then + : + else + echo "*** Could not run SDL test program, checking why..." + CFLAGS="$CFLAGS $SDL_CFLAGS" + CXXFLAGS="$CXXFLAGS $SDL_CFLAGS" + LIBS="$LIBS $SDL_LIBS" + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +#include +#include "SDL.h" + +int main(int argc, char *argv[]) +{ return 0; } +#undef main +#define main K_and_R_C_main +]], [[ return 0; ]])], + [ echo "*** The test program compiled, but did not run. This usually means" + echo "*** that the run-time linker is not finding SDL or finding the wrong" + echo "*** version of SDL. If it is not finding SDL, you'll need to set your" + echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point" + echo "*** to the installed location Also, make sure you have run ldconfig if that" + echo "*** is required on your system" + echo "***" + echo "*** If you have an old version installed, it is best to remove it, although" + echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"], + [ echo "*** The test program failed to compile or link. See the file config.log for the" + echo "*** exact error that occured. This usually means SDL was incorrectly installed" + echo "*** or that you have moved SDL since it was installed. In the latter case, you" + echo "*** may want to edit the sdl-config script: $SDL_CONFIG" ]) + CFLAGS="$ac_save_CFLAGS" + CXXFLAGS="$ac_save_CXXFLAGS" + LIBS="$ac_save_LIBS" + fi + fi + SDL_CFLAGS="" + SDL_LIBS="" + ifelse([$3], , :, [$3]) + fi + AC_SUBST(SDL_CFLAGS) + AC_SUBST(SDL_LIBS) + rm -f conf.sdltest +]) From b9226b07be15bba33d656f8f4082895f82cd5bcb Mon Sep 17 00:00:00 2001 From: David Gow Date: Thu, 10 Jun 2021 15:08:20 +0800 Subject: [PATCH 043/606] Convert SDL2 Scancodes into SDLKey, not SDL2 Keycodes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SDL 1.2's keysym appears to be entirely layout-indpendent: it always acts as though there is a US keyboard layout. i.e., the values represent the positions on the keyboard, not the "meaning" of the key. This matches what SDL 2.0 scancodes do, but not SDL 2.0 keycodes, which are translated according to the current keyboard layout. This means that many SDL 1.2 applications would suddenly start using the user's keyboard layout, rather than the US one, which -- while quite convenient in some cases -- is a change in behaviour and could break things. Instead of converting SDL_Keycode→SDLKey, this patch converts from SDL_Scancode→SDLKey, preserving the original behaviour. SDL 1.2 applications will still get translated values in the 'unicode' Keysym variable if enabled, so text input in many applications will still work as expected. --- src/SDL12_compat.c | 212 ++++++++++++++++++++++++++++----------------- 1 file changed, 131 insertions(+), 81 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index fdc57f086..c05a60ec8 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -2294,88 +2294,138 @@ SDL_GetKeyName(SDL12Key key) } static SDL12Key -Keysym20to12(const SDL_Keycode keysym20) -{ - if (((int) keysym20) < 127) { /* (most of) low-ASCII maps directly */ - if (keysym20 == SDLK_PAUSE) { - return SDLK12_PAUSE; - } else if (keysym20 == SDLK_CLEAR) { - return SDLK12_CLEAR; - } - return (SDL12Key) keysym20; - } - - switch (keysym20) { - #define CASEKEYSYM20TO12(k20, k12) case SDLK_##k20: return SDLK12_##k12 - CASEKEYSYM20TO12(KP_0, KP0); - CASEKEYSYM20TO12(KP_1, KP1); - CASEKEYSYM20TO12(KP_2, KP2); - CASEKEYSYM20TO12(KP_3, KP3); - CASEKEYSYM20TO12(KP_4, KP4); - CASEKEYSYM20TO12(KP_5, KP5); - CASEKEYSYM20TO12(KP_6, KP6); - CASEKEYSYM20TO12(KP_7, KP7); - CASEKEYSYM20TO12(KP_8, KP8); - CASEKEYSYM20TO12(KP_9, KP9); - CASEKEYSYM20TO12(NUMLOCKCLEAR, NUMLOCK); - CASEKEYSYM20TO12(SCROLLLOCK, SCROLLOCK); - CASEKEYSYM20TO12(RGUI, RMETA); - CASEKEYSYM20TO12(LGUI, LMETA); - CASEKEYSYM20TO12(PRINTSCREEN, PRINT); - #undef CASEKEYSYM20TO12 - - #define CASEKEYSYM20TO12(k) case SDLK_##k: return SDLK12_##k - CASEKEYSYM20TO12(CLEAR); - CASEKEYSYM20TO12(PAUSE); - CASEKEYSYM20TO12(KP_PERIOD); - CASEKEYSYM20TO12(KP_DIVIDE); - CASEKEYSYM20TO12(KP_MULTIPLY); - CASEKEYSYM20TO12(KP_MINUS); - CASEKEYSYM20TO12(KP_PLUS); - CASEKEYSYM20TO12(KP_ENTER); - CASEKEYSYM20TO12(KP_EQUALS); - CASEKEYSYM20TO12(UP); - CASEKEYSYM20TO12(DOWN); - CASEKEYSYM20TO12(RIGHT); - CASEKEYSYM20TO12(LEFT); - CASEKEYSYM20TO12(INSERT); - CASEKEYSYM20TO12(HOME); - CASEKEYSYM20TO12(END); - CASEKEYSYM20TO12(PAGEUP); - CASEKEYSYM20TO12(PAGEDOWN); - CASEKEYSYM20TO12(F1); - CASEKEYSYM20TO12(F2); - CASEKEYSYM20TO12(F3); - CASEKEYSYM20TO12(F4); - CASEKEYSYM20TO12(F5); - CASEKEYSYM20TO12(F6); - CASEKEYSYM20TO12(F7); - CASEKEYSYM20TO12(F8); - CASEKEYSYM20TO12(F9); - CASEKEYSYM20TO12(F10); - CASEKEYSYM20TO12(F11); - CASEKEYSYM20TO12(F12); - CASEKEYSYM20TO12(F13); - CASEKEYSYM20TO12(F14); - CASEKEYSYM20TO12(F15); - CASEKEYSYM20TO12(CAPSLOCK); - CASEKEYSYM20TO12(RSHIFT); - CASEKEYSYM20TO12(LSHIFT); - CASEKEYSYM20TO12(RCTRL); - CASEKEYSYM20TO12(LCTRL); - CASEKEYSYM20TO12(RALT); - CASEKEYSYM20TO12(LALT); - CASEKEYSYM20TO12(MODE); - CASEKEYSYM20TO12(HELP); - CASEKEYSYM20TO12(SYSREQ);; - CASEKEYSYM20TO12(MENU); - CASEKEYSYM20TO12(POWER); - CASEKEYSYM20TO12(UNDO); - #undef CASEKEYSYM20TO12 +Scancode20toKeysym12(const SDL_Scancode scancode20) +{ + switch (scancode20) { + #define CASESCANCODE20TOKEY12(s20, k12) case SDL_SCANCODE_##s20: return SDLK12_##k12 + CASESCANCODE20TOKEY12(A,a); + CASESCANCODE20TOKEY12(B,b); + CASESCANCODE20TOKEY12(C,c); + CASESCANCODE20TOKEY12(D,d); + CASESCANCODE20TOKEY12(E,e); + CASESCANCODE20TOKEY12(F,f); + CASESCANCODE20TOKEY12(G,g); + CASESCANCODE20TOKEY12(H,h); + CASESCANCODE20TOKEY12(I,i); + CASESCANCODE20TOKEY12(J,j); + CASESCANCODE20TOKEY12(K,k); + CASESCANCODE20TOKEY12(L,l); + CASESCANCODE20TOKEY12(M,m); + CASESCANCODE20TOKEY12(N,n); + CASESCANCODE20TOKEY12(O,o); + CASESCANCODE20TOKEY12(P,p); + CASESCANCODE20TOKEY12(Q,q); + CASESCANCODE20TOKEY12(R,r); + CASESCANCODE20TOKEY12(S,s); + CASESCANCODE20TOKEY12(T,t); + CASESCANCODE20TOKEY12(U,u); + CASESCANCODE20TOKEY12(V,v); + CASESCANCODE20TOKEY12(W,w); + CASESCANCODE20TOKEY12(X,x); + CASESCANCODE20TOKEY12(Y,y); + CASESCANCODE20TOKEY12(Z,z); + CASESCANCODE20TOKEY12(1,1); + CASESCANCODE20TOKEY12(2,2); + CASESCANCODE20TOKEY12(3,3); + CASESCANCODE20TOKEY12(4,4); + CASESCANCODE20TOKEY12(5,5); + CASESCANCODE20TOKEY12(6,6); + CASESCANCODE20TOKEY12(7,7); + CASESCANCODE20TOKEY12(8,8); + CASESCANCODE20TOKEY12(9,9); + CASESCANCODE20TOKEY12(0,0); + CASESCANCODE20TOKEY12(RETURN,RETURN); + CASESCANCODE20TOKEY12(ESCAPE,ESCAPE); + CASESCANCODE20TOKEY12(BACKSPACE,BACKSPACE); + CASESCANCODE20TOKEY12(TAB,TAB); + CASESCANCODE20TOKEY12(SPACE,SPACE); + CASESCANCODE20TOKEY12(MINUS,MINUS); + CASESCANCODE20TOKEY12(EQUALS,EQUALS); + CASESCANCODE20TOKEY12(LEFTBRACKET,LEFTBRACKET); + CASESCANCODE20TOKEY12(RIGHTBRACKET,RIGHTBRACKET); + CASESCANCODE20TOKEY12(BACKSLASH,BACKSLASH); + CASESCANCODE20TOKEY12(NONUSHASH,HASH); + CASESCANCODE20TOKEY12(SEMICOLON,SEMICOLON); + CASESCANCODE20TOKEY12(APOSTROPHE,QUOTE); + CASESCANCODE20TOKEY12(GRAVE,BACKQUOTE); + CASESCANCODE20TOKEY12(COMMA,COMMA); + CASESCANCODE20TOKEY12(PERIOD,PERIOD); + CASESCANCODE20TOKEY12(SLASH,SLASH); + CASESCANCODE20TOKEY12(CAPSLOCK,CAPSLOCK); + CASESCANCODE20TOKEY12(F1,F1); + CASESCANCODE20TOKEY12(F2,F2); + CASESCANCODE20TOKEY12(F3,F3); + CASESCANCODE20TOKEY12(F4,F4); + CASESCANCODE20TOKEY12(F5,F5); + CASESCANCODE20TOKEY12(F6,F6); + CASESCANCODE20TOKEY12(F7,F7); + CASESCANCODE20TOKEY12(F8,F8); + CASESCANCODE20TOKEY12(F9,F9); + CASESCANCODE20TOKEY12(F10,F10); + CASESCANCODE20TOKEY12(F11,F11); + CASESCANCODE20TOKEY12(F12,F12); + CASESCANCODE20TOKEY12(PRINTSCREEN,PRINT); + CASESCANCODE20TOKEY12(SCROLLLOCK,SCROLLOCK); + CASESCANCODE20TOKEY12(PAUSE,PAUSE); + CASESCANCODE20TOKEY12(INSERT,INSERT); + CASESCANCODE20TOKEY12(HOME,HOME); + CASESCANCODE20TOKEY12(PAGEUP,PAGEUP); + CASESCANCODE20TOKEY12(DELETE,DELETE); + CASESCANCODE20TOKEY12(END,END); + CASESCANCODE20TOKEY12(PAGEDOWN,PAGEDOWN); + CASESCANCODE20TOKEY12(RIGHT,RIGHT); + CASESCANCODE20TOKEY12(LEFT,LEFT); + CASESCANCODE20TOKEY12(DOWN,DOWN); + CASESCANCODE20TOKEY12(UP,UP); + CASESCANCODE20TOKEY12(NUMLOCKCLEAR,NUMLOCK); + + CASESCANCODE20TOKEY12(KP_DIVIDE,KP_DIVIDE); + CASESCANCODE20TOKEY12(KP_MULTIPLY,KP_MULTIPLY); + CASESCANCODE20TOKEY12(KP_MINUS,KP_MINUS); + CASESCANCODE20TOKEY12(KP_PLUS,KP_PLUS); + CASESCANCODE20TOKEY12(KP_ENTER,KP_ENTER); + CASESCANCODE20TOKEY12(KP_1,KP1); + CASESCANCODE20TOKEY12(KP_2,KP2); + CASESCANCODE20TOKEY12(KP_3,KP3); + CASESCANCODE20TOKEY12(KP_4,KP4); + CASESCANCODE20TOKEY12(KP_5,KP5); + CASESCANCODE20TOKEY12(KP_6,KP6); + CASESCANCODE20TOKEY12(KP_7,KP7); + CASESCANCODE20TOKEY12(KP_8,KP8); + CASESCANCODE20TOKEY12(KP_9,KP9); + CASESCANCODE20TOKEY12(KP_0,KP0); + + CASESCANCODE20TOKEY12(NONUSBACKSLASH,BACKSLASH); + /* The description of this could be MENU, or COMPOSE, or neither. */ + CASESCANCODE20TOKEY12(APPLICATION,COMPOSE); + CASESCANCODE20TOKEY12(POWER,POWER); + CASESCANCODE20TOKEY12(F13,F13); + CASESCANCODE20TOKEY12(F14,F14); + CASESCANCODE20TOKEY12(F15,F15); + CASESCANCODE20TOKEY12(KP_EQUALS,KP_EQUALS); + /* SDL 1.2 doesn't support F16..F21 */ + /* Nor SDL_SCANCODE_EXECUTE */ + CASESCANCODE20TOKEY12(HELP,HELP); + CASESCANCODE20TOKEY12(MENU,MENU); + /* The next several scancodes don't have equivalents, until... */ + CASESCANCODE20TOKEY12(SYSREQ,SYSREQ); + CASESCANCODE20TOKEY12(CLEAR,CLEAR); + /* Skip some more... */ + CASESCANCODE20TOKEY12(LCTRL,LCTRL); + CASESCANCODE20TOKEY12(LSHIFT,LSHIFT); + CASESCANCODE20TOKEY12(LALT,LALT); + CASESCANCODE20TOKEY12(LGUI,LSUPER); + CASESCANCODE20TOKEY12(RCTRL,RCTRL); + CASESCANCODE20TOKEY12(RSHIFT,RSHIFT); + CASESCANCODE20TOKEY12(RALT,RALT); + CASESCANCODE20TOKEY12(RGUI,RSUPER); + + CASESCANCODE20TOKEY12(MODE,MODE); + #undef CASESCANCODE20TOKEY12 default: break; } - FIXME("nothing maps to SDLK12_COMPOSE, SDLK12_BREAK, or SDLK12_EURO ...?"); + FIXME("nothing maps to SDLK12_BREAK, or SDLK12_EURO ...?"); FIXME("map some of the SDLK12_WORLD keys"); return SDLK12_UNKNOWN; } @@ -2646,7 +2696,7 @@ EventFilter20to12(void *data, SDL_Event *event20) if (event20->key.repeat) { return 1; /* ignore 2.0-style key repeat events */ } - event12.key.keysym.sym = Keysym20to12(event20->key.keysym.sym); + event12.key.keysym.sym = Scancode20toKeysym12(event20->key.keysym.scancode); KeyState[event12.key.keysym.sym] = event20->key.state; @@ -2668,7 +2718,7 @@ EventFilter20to12(void *data, SDL_Event *event20) return 1; /* ignore 2.0-style key repeat events */ } - PendingKeydownEvent.key.keysym.sym = Keysym20to12(event20->key.keysym.sym); + PendingKeydownEvent.key.keysym.sym = Scancode20toKeysym12(event20->key.keysym.scancode); KeyState[PendingKeydownEvent.key.keysym.sym] = event20->key.state; From f7e60cd37e29e43ef30f350117fe7424225afa07 Mon Sep 17 00:00:00 2001 From: David Gow Date: Thu, 10 Jun 2021 14:29:30 +0800 Subject: [PATCH 044/606] Fix scancode for LCTRL on Mac OS. This was a typo: it accidentally was 4B (KP_DIVIDE) rather than 3B (LCTRL). This should fix the Left Control key in DOSBox on Macs with usescancodes=true --- src/SDL12_compat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index fdc57f086..30cee4fe0 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -2467,7 +2467,7 @@ Scancode20to12(SDL_Scancode sc) CASESCANCODE20TO12(KP_PLUS, 0x56, 0x44); CASESCANCODE20TO12(L, 0x2E, 0x25); CASESCANCODE20TO12(LALT, 0x40, 0x3A); - CASESCANCODE20TO12(LCTRL, 0x25, 0x4B); + CASESCANCODE20TO12(LCTRL, 0x25, 0x3B); CASESCANCODE20TO12(LEFT, 0x00, 0x7B); CASESCANCODE20TO12(LEFTBRACKET, 0x22, 0x21); CASESCANCODE20TO12(LGUI, 0x85, 0x37); From acd719c5aade255fc1dd4428ae39a9f1cf6de76c Mon Sep 17 00:00:00 2001 From: David Gow Date: Thu, 10 Jun 2021 17:23:01 +0800 Subject: [PATCH 045/606] The Command key should be exposed as META on macOS SDL 1.2 uses {L,R}META for the Command key on macOS. It uses {L,R}SUPER for the windows logo key on Windows/Linux. SDL 2.0 maps both of these to {L,R}GUI. Just select between them at compile time. --- src/SDL12_compat.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index c05a60ec8..d795ae142 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -2414,11 +2414,19 @@ Scancode20toKeysym12(const SDL_Scancode scancode20) CASESCANCODE20TOKEY12(LCTRL,LCTRL); CASESCANCODE20TOKEY12(LSHIFT,LSHIFT); CASESCANCODE20TOKEY12(LALT,LALT); +#ifdef __MACOSX__ + CASESCANCODE20TOKEY12(LGUI,LMETA); +#else CASESCANCODE20TOKEY12(LGUI,LSUPER); +#endif CASESCANCODE20TOKEY12(RCTRL,RCTRL); CASESCANCODE20TOKEY12(RSHIFT,RSHIFT); CASESCANCODE20TOKEY12(RALT,RALT); +#ifdef __MACOSX__ + CASESCANCODE20TOKEY12(RGUI,RMETA); +#else CASESCANCODE20TOKEY12(RGUI,RSUPER); +#endif CASESCANCODE20TOKEY12(MODE,MODE); #undef CASESCANCODE20TOKEY12 From 0ee69695fd453993de86627b8a9c29f0976390e0 Mon Sep 17 00:00:00 2001 From: David Gow Date: Thu, 10 Jun 2021 17:27:17 +0800 Subject: [PATCH 046/606] The APPLICATION key should actually map to MENU. This is described in the SDL 2.0 docs as being either a compose key (notably an actual, hardware compose key like the type seen on old Sun keyboards) or the windows contextual menu. On my Linux/X11 machine with a Microsoft USB keyboard, this is the scancode the contextual menu uses. (What, if anything, ever produces the MENU scancode is a mystery for another day, I guess...) --- src/SDL12_compat.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index d795ae142..6ff500016 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -2396,8 +2396,8 @@ Scancode20toKeysym12(const SDL_Scancode scancode20) CASESCANCODE20TOKEY12(KP_0,KP0); CASESCANCODE20TOKEY12(NONUSBACKSLASH,BACKSLASH); - /* The description of this could be MENU, or COMPOSE, or neither. */ - CASESCANCODE20TOKEY12(APPLICATION,COMPOSE); + /* In theory, this could be MENU, or COMPOSE, or neither, but on my machine, it's MENU. */ + CASESCANCODE20TOKEY12(APPLICATION,MENU); CASESCANCODE20TOKEY12(POWER,POWER); CASESCANCODE20TOKEY12(F13,F13); CASESCANCODE20TOKEY12(F14,F14); From e1d7b809d73715491a18db4fe6e2ec7557dfb32a Mon Sep 17 00:00:00 2001 From: David Gow Date: Thu, 10 Jun 2021 21:04:59 +0800 Subject: [PATCH 047/606] Modifier keys on Mac OS X do not have scancodes This actually fixes three related issues: - Modifier keys on OS X should have "unknown" scancodes - Unknown scancodes on OS X should have the value 0, even though that conflicts with the scancode for "a" - RGUI and RSHIFT should have scancodes on non-OSX platforms. SDL 1.2's Quartz backend, used on Mac OS X, always gives modifier keys a scancode of 0, even though OS X actually does have a scancode number for them. This can be seen (both for < OS X 10.3, where left and right modifiers could not be distinguished, and for newer versions where they can) in the implementation here: https://github.com/libsdl-org/SDL-1.2/blob/02c0253780c8a36569b271500a37591ab80e923d/src/video/quartz/SDL_QuartzEvents.m#L475 Applications such as DOSBox rely heavily on this behaviour, and the keys will not function in the default "usescancodes=true" mode if a scancode other than 0 is returned for the right-hand-side modifier keys. This can be seen in sdl12-compat GitHub issue #84, where the issue was analysed: https://github.com/libsdl-org/sdl12-compat/issues/84#issuecomment-858597299 --- src/SDL12_compat.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 30cee4fe0..12f3a0c77 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -2418,7 +2418,7 @@ Scancode20to12(SDL_Scancode sc) CASESCANCODE20TO12(BACKSLASH, 0x33, 0x2A); CASESCANCODE20TO12(BACKSPACE, 0x16, 0x33); CASESCANCODE20TO12(C, 0x36, 0x08); - CASESCANCODE20TO12(CAPSLOCK, 0x42, 0x39); + CASESCANCODE20TO12(CAPSLOCK, 0x42, 0x00); CASESCANCODE20TO12(COMMA, 0x3B, 0x2B); CASESCANCODE20TO12(D, 0x28, 0x02); CASESCANCODE20TO12(DELETE, 0x00, 0x75); @@ -2466,12 +2466,12 @@ Scancode20to12(SDL_Scancode sc) CASESCANCODE20TO12(KP_PERIOD, 0x5B, 0x41); CASESCANCODE20TO12(KP_PLUS, 0x56, 0x44); CASESCANCODE20TO12(L, 0x2E, 0x25); - CASESCANCODE20TO12(LALT, 0x40, 0x3A); - CASESCANCODE20TO12(LCTRL, 0x25, 0x3B); + CASESCANCODE20TO12(LALT, 0x40, 0x00); + CASESCANCODE20TO12(LCTRL, 0x25, 0x00); CASESCANCODE20TO12(LEFT, 0x00, 0x7B); CASESCANCODE20TO12(LEFTBRACKET, 0x22, 0x21); - CASESCANCODE20TO12(LGUI, 0x85, 0x37); - CASESCANCODE20TO12(LSHIFT, 0x32, 0x38); + CASESCANCODE20TO12(LGUI, 0x85, 0x00); + CASESCANCODE20TO12(LSHIFT, 0x32, 0x00); CASESCANCODE20TO12(M, 0x3A, 0x29); CASESCANCODE20TO12(MINUS, 0x14, 0x1B); CASESCANCODE20TO12(N, 0x39, 0x28); @@ -2485,8 +2485,10 @@ Scancode20to12(SDL_Scancode sc) CASESCANCODE20TO12(Q, 0x18, 0x0C); CASESCANCODE20TO12(R, 0x1B, 0x0F); CASESCANCODE20TO12(RETURN, 0x24, 0x24); + CASESCANCODE20TO12(RGUI, 0x86, 0x00); CASESCANCODE20TO12(RIGHT, 0x00, 0x7C); CASESCANCODE20TO12(RIGHTBRACKET, 0x23, 0x1E); + CASESCANCODE20TO12(RSHIFT, 0x3E, 0x00); CASESCANCODE20TO12(S, 0x27, 0x01); CASESCANCODE20TO12(SCROLLLOCK, 0x4E, 0x71); CASESCANCODE20TO12(SEMICOLON, 0x2F, 0x29); @@ -2503,13 +2505,9 @@ Scancode20to12(SDL_Scancode sc) CASESCANCODE20TO12(Z, 0x34, 0x06); #undef CASESCANCODE20TO12 default: - /* If we don't know it, return 0, which is "unknown" on everything - except Mac OS X, where it's "A" for whatever reason. */ -#ifdef __MACOSX__ - return 0x34; /* DOSBox should treat this as unknown. */ -#else + /* If we don't know it, return 0, which is "unknown". + It's also "a" on Mac OS X, but SDL 1.2 uses it as "unknown", too. */ return 0; -#endif } return 0; } From a309f3bd5d1629eb4602e9be3e92db38de84a1f0 Mon Sep 17 00:00:00 2001 From: David Gow Date: Thu, 10 Jun 2021 17:48:50 +0800 Subject: [PATCH 048/606] checkkeys: Unconditionally display the scancode It's useful for debugging what scancodes are used by SDL 1.2 (particularly across different platforms) if checkkeys displays it even when it does successfully map it to an SDLKey. In addition, print the scancode in hex as well as decimal, as the hardcoded values we're using in sdl12-compat are all in hex. --- test/checkkeys.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/checkkeys.c b/test/checkkeys.c index 8dbb24f94..b37da9305 100644 --- a/test/checkkeys.c +++ b/test/checkkeys.c @@ -54,10 +54,10 @@ static void PrintKey(SDL_keysym *sym, int pressed) { /* Print the keycode, name and state */ if ( sym->sym ) { - printf("Key %s: %d-%s ", pressed ? "pressed" : "released", - sym->sym, SDL_GetKeyName(sym->sym)); + printf("Key %s: %d-%s (scancode = %d [0x%x])", pressed ? "pressed" : "released", + sym->sym, SDL_GetKeyName(sym->sym), sym->scancode, sym->scancode); } else { - printf("Unknown Key (scancode = %d) %s ", sym->scancode, + printf("Unknown Key (scancode = %d [0x%x]) %s ", sym->scancode, sym->scancode, pressed ? "pressed" : "released"); } From 21830e8e81646e5c2969e45eeb4ab0b93319d621 Mon Sep 17 00:00:00 2001 From: Neal Gompa Date: Wed, 9 Jun 2021 08:16:36 -0400 Subject: [PATCH 049/606] cmake: Add support to build the static library A static link library is not ideal, since we cannot statically link SDL2 into this library. However, some projects demand a static library to build, so optionally provide a way to build it so those projects can use this library instead of SDL-1.2. --- CMakeLists.txt | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 796dc0b6f..b896e820c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,6 +11,7 @@ set(SDL12_COMPAT_VERSION_STR "1.2.50") option(SDL12TESTS "Enable to build SDL-1.2 test programs" ON) option(SDL12DEVEL "Enable installing SDL-1.2 development headers" ON) +option(STATICDEVEL "Enable installing static link library" OFF) set(CMAKE_SKIP_RPATH TRUE) @@ -202,3 +203,42 @@ if(SDL12DEVEL) install(FILES "${CMAKE_SOURCE_DIR}/sdl.m4" DESTINATION "${CMAKE_INSTALL_FULL_DATAROOTDIR}/aclocal") endif() +if(STATICDEVEL AND SDL12DEVEL) + add_library(SDL-static STATIC ${SDL12COMPAT_SRCS}) + target_include_directories(SDL-static PRIVATE ${SDL2_INCLUDE_DIRS}) + if(UNIX AND NOT APPLE) + set_target_properties(SDL-static PROPERTIES COMPILE_DEFINITIONS "_REENTRANT") + target_link_libraries(SDL-static PRIVATE dl) + endif() + if(APPLE) + set_target_properties(SDL-static PROPERTIES COMPILE_DEFINITIONS "_THREAD_SAFE") + target_link_libraries(SDL-static PRIVATE "-framework AppKit") + set_target_properties(SDL-static PROPERTIES + MACOSX_RPATH 1 + OUTPUT_NAME "SDL" + ) + else() + set_target_properties(SDL-static PROPERTIES + VERSION "${SDL12_COMPAT_VERSION_STR}" + OUTPUT_NAME "SDL") + endif() + + if(MINGW) + set_target_properties(SDL-static PROPERTIES LINK_FLAGS "-nostdlib") + endif() + if(MSVC) + # Don't try to link with the default set of libraries. + set_target_properties(SDL-static PROPERTIES COMPILE_FLAGS "/GS-") + set_target_properties(SDL-static PROPERTIES LINK_FLAGS "/NODEFAULTLIB") + # Make sure /RTC1 is disabled: (from SDL2 CMake) + foreach(flag_var + CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE + CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO) + string(REGEX REPLACE "/RTC(su|[1su])" "" ${flag_var} "${${flag_var}}") + endforeach(flag_var) + endif() + + install(TARGETS SDL-static + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + ) +endif() From ffd09b017f3a0d08133c164975bee8997ab890d7 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 10 Jun 2021 14:15:47 -0400 Subject: [PATCH 050/606] cmake: don't build OpenGL test programs if OpenGL isn't available. Fixes #90. --- CMakeLists.txt | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b896e820c..c897b7d1a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -94,15 +94,20 @@ if(SDL12TESTS) find_library(MATH_LIBRARY m) endif() + find_package(OpenGL COMPONENTS OpenGL) + if(OpenGL_FOUND) + set(HAVE_OPENGL_DEFINE "HAVE_OPENGL") + endif() + macro(test_program _NAME _SRCS) add_executable(${_NAME} ${_SRCS}) target_include_directories(${_NAME} PRIVATE "include/SDL") target_link_libraries(${_NAME} SDL) # Turn off MSVC's aggressive C runtime warnings for the old test programs. if(MSVC) - set_target_properties(${_NAME} PROPERTIES COMPILE_DEFINITIONS "HAVE_OPENGL;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE") + set_target_properties(${_NAME} PROPERTIES COMPILE_DEFINITIONS "${HAVE_OPENGL_DEFINE};_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE") else() - set_target_properties(${_NAME} PROPERTIES COMPILE_DEFINITIONS "HAVE_OPENGL") + set_target_properties(${_NAME} PROPERTIES COMPILE_DEFINITIONS "${HAVE_OPENGL_DEFINE}") endif() if(MATH_LIBRARY) target_link_libraries(${_NAME} ${MATH_LIBRARY}) @@ -117,11 +122,9 @@ if(SDL12TESTS) test_program(testblitspeed "test/testblitspeed.c") test_program(testcdrom "test/testcdrom.c") test_program(testcursor "test/testcursor.c") - test_program(testdyngl "test/testdyngl.c") test_program(testerror "test/testerror.c") test_program(testfile "test/testfile.c") test_program(testgamma "test/testgamma.c") - test_program(testgl "test/testgl.c") test_program(testthread "test/testhread.c") test_program(testiconv "test/testiconv.c") test_program(testjoystick "test/testjoystick.c") @@ -142,11 +145,11 @@ if(SDL12TESTS) test_program(threadwin "test/threadwin.c") test_program(torturethread "test/torturethread.c") - if(WIN32) - target_link_libraries(testgl "OpenGL32") - else() - find_package(OpenGL COMPONENTS OpenGL REQUIRED) + if(OpenGL_FOUND) + test_program(testdyngl "test/testdyngl.c") + # testgl links directly to OpenGL (yuck), whereas testdyngl doesn't. + test_program(testgl "test/testgl.c") if(CMAKE_VERSION VERSION_LESS 3.10) target_link_libraries(testgl ${OPENGL_gl_LIBRARY}) else() From 8323fed73071b32073c6eb9ca00b7860827d2f32 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 10 Jun 2021 14:32:12 -0400 Subject: [PATCH 051/606] cmake: Fix Windows build...again. --- CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index c897b7d1a..0744f9ce7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -97,6 +97,10 @@ if(SDL12TESTS) find_package(OpenGL COMPONENTS OpenGL) if(OpenGL_FOUND) set(HAVE_OPENGL_DEFINE "HAVE_OPENGL") + if(WIN32) + set(${OPENGL_gl_LIBRARY} "OpenGL32") + set(${OPENGL_opengl_LIBRARY} "OpenGL32") + endif() endif() macro(test_program _NAME _SRCS) From 25ae1571ce84af4144ad5ea8380f39bd026ee0fb Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 10 Jun 2021 14:43:59 -0400 Subject: [PATCH 052/606] cmake: fixed silly mistake --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0744f9ce7..82c30174f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -98,8 +98,8 @@ if(SDL12TESTS) if(OpenGL_FOUND) set(HAVE_OPENGL_DEFINE "HAVE_OPENGL") if(WIN32) - set(${OPENGL_gl_LIBRARY} "OpenGL32") - set(${OPENGL_opengl_LIBRARY} "OpenGL32") + set(OPENGL_gl_LIBRARY "OpenGL32") + set(OPENGL_opengl_LIBRARY "OpenGL32") endif() endif() From 3e1375d4e771584104e4402e09f7fe9965029c82 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Thu, 10 Jun 2021 23:01:02 +0300 Subject: [PATCH 053/606] Makefile.mingw: add a note about libgcc requirement. --- src/Makefile.mingw | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Makefile.mingw b/src/Makefile.mingw index b31e890c6..1130a9c66 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -18,6 +18,7 @@ CPPFLAGS = -DDLL_EXPORT -DNDEBUG CFLAGS = -O3 -Wall LDFLAGS = -nostdlib -shared -Wl,--no-undefined -Wl,--enable-auto-image-base -Wl,--out-implib,$(LIB) LDLIBS = -lkernel32 -luser32 +# libgcc is needed for 32 bit (x86) builds: LDLIBS += -static-libgcc -lgcc LIB = libSDL.dll.a From 12ac5f6d07028dceba21ba687e05b3d103d4d012 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Thu, 10 Jun 2021 23:01:04 +0300 Subject: [PATCH 054/606] avoid exporting drmp3 symbols. Closes: https://github.com/libsdl-org/sdl12-compat/pull/101 --- src/SDL12_compat.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 12f3a0c77..255d37ef2 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -5815,6 +5815,12 @@ SDL_LoadWAV_RW(SDL12_RWops *rwops12, int freerwops12, /* public domain, single-header MP3 decoder for fake CD-ROM audio support! */ #define DR_MP3_IMPLEMENTATION +#if defined(__GNUC__) && (__GNUC__ >= 4) && \ + !(defined(_WIN32) || defined(__EMX__)) +#define DRMP3_API __attribute__((visibility("hidden"))) +#elif defined(__APPLE__) +#define DRMP3_API __private_extern__ +#endif #define DR_MP3_NO_STDIO 1 #define DR_MP3_NO_S16 1 #define DR_MP3_FLOAT_OUTPUT 1 From 61d5c5af29c4802eddaa0a2baa270b11d2d0f5fd Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Fri, 11 Jun 2021 04:00:02 +0300 Subject: [PATCH 055/606] Scancode20to12: removed unreached return statement. --- src/SDL12_compat.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index b7c9d1442..851ee7b56 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -2561,13 +2561,12 @@ Scancode20to12(SDL_Scancode sc) CASESCANCODE20TO12(X, 0x35, 0x07); CASESCANCODE20TO12(Y, 0x1D, 0x10); CASESCANCODE20TO12(Z, 0x34, 0x06); -#undef CASESCANCODE20TO12 +#undef CASESCANCODE20TO12 default: /* If we don't know it, return 0, which is "unknown". It's also "a" on Mac OS X, but SDL 1.2 uses it as "unknown", too. */ return 0; } - return 0; } DECLSPEC Uint8 * SDLCALL From a2de2d6466928ffb813231d286b4b75e75322307 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 10 Jun 2021 21:51:28 -0400 Subject: [PATCH 056/606] cmake: don't use add_definitions. Reference issue #85. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 82c30174f..d1309f0f6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,7 +39,7 @@ include("cmake/modules/FindSDL2.cmake") target_include_directories(SDL PRIVATE ${SDL2_INCLUDE_DIRS}) if (CMAKE_C_COMPILER_ID MATCHES "Clang|GNU") - add_definitions("-Wall -Werror=declaration-after-statement") # force these universally. + add_compile_options(-Wall -Werror=declaration-after-statement) # force these universally. endif() # avoid DLL having 'lib' prefix with Windows MinGW builds From 7848987cbd5c15caefbc74c88476d70d247419f8 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Fri, 11 Jun 2021 07:29:00 +0300 Subject: [PATCH 057/606] lowercase 'opengl32' --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d1309f0f6..200acb626 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -98,8 +98,8 @@ if(SDL12TESTS) if(OpenGL_FOUND) set(HAVE_OPENGL_DEFINE "HAVE_OPENGL") if(WIN32) - set(OPENGL_gl_LIBRARY "OpenGL32") - set(OPENGL_opengl_LIBRARY "OpenGL32") + set(OPENGL_gl_LIBRARY "opengl32") + set(OPENGL_opengl_LIBRARY "opengl32") endif() endif() From 0a951c0d094990accf4921f20e7f76b5b3dc2cb9 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Fri, 11 Jun 2021 07:30:56 +0300 Subject: [PATCH 058/606] don't use add_compile_options for CFLAGS, set CMAKE_C_FLAGS, instead. see https://github.com/libsdl-org/sdl12-compat/issues/85#issuecomment-858932501 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 200acb626..1459c9188 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,7 +39,7 @@ include("cmake/modules/FindSDL2.cmake") target_include_directories(SDL PRIVATE ${SDL2_INCLUDE_DIRS}) if (CMAKE_C_COMPILER_ID MATCHES "Clang|GNU") - add_compile_options(-Wall -Werror=declaration-after-statement) # force these universally. + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Werror=declaration-after-statement") # force these universally. endif() # avoid DLL having 'lib' prefix with Windows MinGW builds From d223c862d80f0a757e5bc28a3a0eaf2f183395c2 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Fri, 11 Jun 2021 07:55:10 +0300 Subject: [PATCH 059/606] mac, error_dialog(): avoid warning from old Apple gcc versions: src/SDL12_compat_objc.m: In function 'error_dialog': src/SDL12_compat_objc.m:61: warning: ISO C90 forbids mixed declarations and code --- src/SDL12_compat_objc.m | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/SDL12_compat_objc.m b/src/SDL12_compat_objc.m index 5c9031425..79966d271 100644 --- a/src/SDL12_compat_objc.m +++ b/src/SDL12_compat_objc.m @@ -49,6 +49,8 @@ SDL12_PRIVATE void sdl12_compat_macos_init(void) SDL12_PRIVATE void error_dialog(const char *errorMsg) { + NSAlert *alert; + if (NSApp == nil) { ProcessSerialNumber psn = { 0, kCurrentProcess }; TransformProcessType(&psn, kProcessTransformToForegroundApplication); @@ -58,7 +60,7 @@ SDL12_PRIVATE void error_dialog(const char *errorMsg) } [NSApp activateIgnoringOtherApps:YES]; - NSAlert *alert = [[[NSAlert alloc] init] autorelease]; + alert = [[[NSAlert alloc] init] autorelease]; alert.alertStyle = NSAlertStyleCritical; alert.messageText = @"Fatal error! Cannot continue!"; alert.informativeText = [NSString stringWithCString:errorMsg encoding:NSASCIIStringEncoding]; From 9ab4eff9c08c9310c5a96ddcfc94100cf8ef65f0 Mon Sep 17 00:00:00 2001 From: David Gow Date: Fri, 11 Jun 2021 17:36:40 +0800 Subject: [PATCH 060/606] Close audio device in SDL_Quit{,Subsystem} Given we allocate and use a bunch of wrappers around the SDL audio device, we should shut it down explicitly on quit. The simplest way to implement this was to just call our SDL_CloseAudio() implementation in SDL_QuitSubsystem(), which require making it robust against closing an already closed audio device. This fixes a sporadic null pointer access in the audio callback on DOSBox on one of my machines. --- src/SDL12_compat.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 851ee7b56..8cfc3505f 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1710,6 +1710,10 @@ SDL_QuitSubSystem(Uint32 sdl12flags) QuitCDSubsystem(); } + if (sdl12flags & SDL12_INIT_AUDIO) { + SDL_CloseAudio(); + } + if (sdl12flags & SDL12_INIT_VIDEO) { Quit12Video(); } @@ -6775,12 +6779,11 @@ SDL_CloseAudio(void) SDL20_LockAudio(); if (audio_cbdata) { audio_cbdata->app_callback_opened = SDL_FALSE; + SDL20_FreeAudioStream(audio_cbdata->app_callback_stream); + audio_cbdata->app_callback_stream = NULL; } SDL20_UnlockAudio(); - SDL20_FreeAudioStream(audio_cbdata->app_callback_stream); - audio_cbdata->app_callback_stream = NULL; - CloseSDL2AudioDevice(); } From bc754b6280ad24632e8bf9882cee74bb7f812b3d Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sat, 12 Jun 2021 10:03:40 +0300 Subject: [PATCH 061/606] cmake: add '-static-libgcc -lgcc' to mingw builds: libgcc is needed for 32 bit (x86) builds. FIXME: MSVC builds linkage needs fixing, too. --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1459c9188..b30d27594 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -75,6 +75,7 @@ endif() if(MINGW) set_target_properties(SDL PROPERTIES LINK_FLAGS "-nostdlib") + target_link_libraries(SDL PRIVATE "-static-libgcc -lgcc") # libgcc is needed for 32 bit (x86) builds endif() if(MSVC) # Don't try to link with the default set of libraries. From c0504eb42c7cabc23c6b4a16f5915ee49962ddff Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sat, 12 Jun 2021 20:15:30 +0300 Subject: [PATCH 062/606] add resource to windows watcom builds --- src/Makefile.w32 | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Makefile.w32 b/src/Makefile.w32 index 833a202c0..ae610e6f8 100644 --- a/src/Makefile.w32 +++ b/src/Makefile.w32 @@ -1,4 +1,4 @@ -# OpenWatcom makefile to build SDL for Win32. +# OpenWatcom makefile to build SDL for Win32 !ifndef %WATCOM !error Environment variable WATCOM is not specified! @@ -28,19 +28,20 @@ CFLAGS+= -wcd=200 # newer OpenWatcom versions enable W303 by default CFLAGS+= -wcd=303 -DESCRIPTION = Simple DirectMedia Layer 1.2 - object_files= SDL12_compat.obj +resource_obj= version.res .extensions: -.extensions: .lib .dll .obj .c .asm +.extensions: .lib .dll .obj .c .asm .res .rc .c.obj: wcc386 $(CFLAGS) -fo=$^@ $< +.rc.res: + wrc -q -r -bt=nt -I"$(%WATCOM)/h/nt" -fo=$^@ $< all: $(DLLFILE) $(LIBFILE) .symbolic -$(DLLFILE): compiling_info $(object_files) $(LNKFILE) +$(DLLFILE): compiling_info $(object_files) $(resource_obj) $(LNKFILE) @echo * Linking: $@ @wlink @$(LNKFILE) @@ -58,18 +59,17 @@ $(LNKFILE): @%append $@ NAME $(DLLFILE) @for %i in ($(object_files)) do @%append $@ FILE %i @%append $@ EXPORT=SDL12.lbc + @%append $@ OPTION RESOURCE=$(resource_obj) @%append $@ OPTION QUIET - @%append $@ OPTION IMPF=$^&.exp @%append $@ OPTION MAP=$^&.map - @%append $@ OPTION DESCRIPTION '@$#libsdl org:$(VERSION)$#@$(DESCRIPTION)' @%append $@ OPTION ELIMINATE @%append $@ OPTION SHOWDEAD clean: .SYMBOLIC @echo * Clean: $(LIBNAME) $(VERSION) @if exist *.obj rm *.obj + @if exist *.res rm *.res @if exist *.map rm *.map - @if exist *.exp rm *.exp @if exist $(LNKFILE) rm $(LNKFILE) distclean: clean .SYMBOLIC From 44f299f49f60ba8985ac08eb997c823005099929 Mon Sep 17 00:00:00 2001 From: David Gow Date: Thu, 3 Jun 2021 21:28:03 +0800 Subject: [PATCH 063/606] Add some common video modes to the modes list MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some modern platforms (e.g. Wayland on KDE) don't expose any video modes other than the current desktop resolution. For games which expect a number of common VGA video modes to be available, this can result in there either being no way to change resolution, or the game failing to start due to a mode not being available. Therefore, fake support for a number of common resolutions: - 640×480 - 800×600 - 1024×768 - 1280×720 - 1920×1080 These are added to the mode list for all available pixel formats for which there exists a valid, larger mode. The modes are included sorted in the correct position within the mode list. The SDL_VideoModeOK() function now uses the fake 1.2 modelist, so picks up these modes. If OpenGL Logical Scaling is explicitly disabled by the user, these modes will not be added, as they may not function correctly if selected (and the application uses OpenGL). --- src/SDL12_compat.c | 119 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 92 insertions(+), 27 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 8cfc3505f..c36de9d45 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1439,6 +1439,58 @@ GetVideoDisplay(void) } } +/* returns true if mode1 should sort before mode2 */ +static int +VidModeSizeGreater(SDL12_Rect *mode1, SDL12_Rect *mode2) +{ + if (mode1->w > mode2->w) { + return 1; + } else if (mode2->w > mode1->w) { + return 0; + } else { + return (mode1->h > mode2->h); + } +} + +static int +AddVidModeToList(VideoModeList *vmode, SDL12_Rect *mode) +{ + void *ptr = NULL; + int i; + + /* make sure we don't have this one already (with a different refresh rate, etc). */ + for (i = 0; i < vmode->nummodes; i++) { + if ((vmode->modeslist12[i].w == mode->w) && (vmode->modeslist12[i].h == mode->h)) { + break; + } + } + + if (i < vmode->nummodes) { + return 0; /* already have this one. */ + } + + ptr = SDL20_realloc(vmode->modeslist12, sizeof (SDL12_Rect) * (vmode->nummodes + 1)); + if (ptr == NULL) { + return SDL20_OutOfMemory(); + } + vmode->modeslist12 = (SDL12_Rect *) ptr; + + vmode->modeslist12[vmode->nummodes] = *mode; + + vmode->nummodes++; + + return 0; +} + +/* A list of fake video modes which are included. */ +static SDL12_Rect fake_modes[] = { + { 0, 0, 1920, 1080 }, + { 0, 0, 1280, 720 }, + { 0, 0, 1024, 768 }, + { 0, 0, 800, 600 }, + { 0, 0, 640, 480 } +}; + /* This sets up VideoModes and VideoModesCount. You end up with arrays by pixel format, each with a value that 1.2's SDL_ListModes() can return. */ static int @@ -1448,6 +1500,10 @@ Init12VidModes(void) VideoModeList *vmode = NULL; void *ptr = NULL; int i, j; + SDL12_Rect prev_mode = { 0, 0, 0, 0 }, current_mode = { 0, 0, 0, 0 }; + /* We only want to enable fake modes if OpenGL Logical Scaling is enabled. */ + char *env = SDL20_getenv("SDL12COMPAT_OPENGL_SCALING"); + SDL_bool use_fake_modes = (!env || SDL20_atoi(env)) ? SDL_TRUE : SDL_FALSE; if (VideoModesCount > 0) { return 0; /* already did this. */ @@ -1483,29 +1539,37 @@ Init12VidModes(void) VideoModesCount++; } - /* make sure we don't have this one already (with a different refresh rate, etc). */ - for (j = 0; j < vmode->nummodes; j++) { - if ((vmode->modeslist12[j].w == mode.w) && (vmode->modeslist12[j].h == mode.h)) { - break; - } - } + current_mode.w = mode.w; + current_mode.h = mode.h; - if (j < vmode->nummodes) { - continue; /* already have this one. */ + /* Attempt to add all of the fake modes. */ + if (use_fake_modes) { + for (j = 0; j < sizeof(fake_modes) / sizeof(fake_modes[0]); ++j) { + if (VidModeSizeGreater(&prev_mode, &fake_modes[j]) && VidModeSizeGreater(&fake_modes[j], ¤t_mode)) { + if (AddVidModeToList(vmode, &fake_modes[j])) { + return SDL20_OutOfMemory(); + } + } + } } - ptr = SDL20_realloc(vmode->modeslist12, sizeof (SDL12_Rect) * (vmode->nummodes + 1)); - if (ptr == NULL) { + if (AddVidModeToList(vmode, ¤t_mode)) { return SDL20_OutOfMemory(); } - vmode->modeslist12 = (SDL12_Rect *) ptr; - vmode->modeslist12[vmode->nummodes].x = 0; - vmode->modeslist12[vmode->nummodes].y = 0; - vmode->modeslist12[vmode->nummodes].w = mode.w; - vmode->modeslist12[vmode->nummodes].h = mode.h; + prev_mode.w = mode.w; + prev_mode.h = mode.h; + } - vmode->nummodes++; + /* we need to try to add fake modes to the end of the list once there are no more real modes */ + if (use_fake_modes) { + for (i = 0; i < sizeof(fake_modes) / sizeof(fake_modes[0]); ++i) { + if (VidModeSizeGreater(&prev_mode, &fake_modes[i])) { + if (AddVidModeToList(vmode, &fake_modes[i])) { + return SDL20_OutOfMemory(); + } + } + } } /* link up modes12 for SDL_ListModes()'s use... */ @@ -3317,7 +3381,7 @@ SDL_GetVideoInfo(void) DECLSPEC int SDLCALL SDL_VideoModeOK(int width, int height, int bpp, Uint32 sdl12flags) { - int i, nummodes, actual_bpp = 0; + int i, j, actual_bpp = 0; if (!SDL20_WasInit(SDL_INIT_VIDEO)) { return 0; @@ -3329,16 +3393,17 @@ SDL_VideoModeOK(int width, int height, int bpp, Uint32 sdl12flags) return SDL_BITSPERPIXEL(mode.format); } - nummodes = SDL20_GetNumDisplayModes(VideoDisplayIndex); - for (i = 0; i < nummodes; ++i) { - SDL_DisplayMode mode; - SDL20_GetDisplayMode(VideoDisplayIndex, i, &mode); - if (!mode.w || !mode.h || (width == mode.w && height == mode.h)) { - if (!mode.format) { - return bpp; - } - if (SDL_BITSPERPIXEL(mode.format) >= (Uint32) bpp) { - actual_bpp = SDL_BITSPERPIXEL(mode.format); + for (i = 0; i < VideoModesCount; ++i) { + VideoModeList *vmode = &VideoModes[i]; + for (j = 0; j < vmode->nummodes; ++j) { + if (vmode->modeslist12[j].w == width && vmode->modeslist12[j].h == height) + { + if (!vmode->format) { + return bpp; + } + if (SDL_BITSPERPIXEL(vmode->format) >= (Uint32) bpp) { + actual_bpp = SDL_BITSPERPIXEL(vmode->format); + } } } } From 57e5d7382c8e901d793cc09a0c8f27f418598782 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Mon, 14 Jun 2021 01:40:02 +0300 Subject: [PATCH 064/606] FIXME: SDL_CFLAGS, SDL_LIBS, SDL_STATIC_LIBS should be target-specific. added the FIXME note to CMakeLists.txt. --- CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index b30d27594..c7da0d958 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -177,6 +177,8 @@ install(TARGETS SDL if(SDL12DEVEL) set(SDL_VERSION "${SDL12_COMPAT_VERSION_STR}") + + # FIXME: Make the following target-specific!! set(SDL_CFLAGS "-D_GNU_SOURCE=1 -D_REENTRANT") set(SDL_RLD_FLAGS "") # !!! FIXME: this forces rpath, which we might want? set(SDL_LIBS "-lSDL") From 366603756d46fd7647c46b4b09585ce051a317f8 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Mon, 14 Jun 2021 01:40:04 +0300 Subject: [PATCH 065/606] cmake: fixes for OPENGL_FOUND stuff tested with cmake versions down to 3.0.0 --- CMakeLists.txt | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c7da0d958..7139f96f3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -96,7 +96,7 @@ if(SDL12TESTS) endif() find_package(OpenGL COMPONENTS OpenGL) - if(OpenGL_FOUND) + if(OPENGL_FOUND) set(HAVE_OPENGL_DEFINE "HAVE_OPENGL") if(WIN32) set(OPENGL_gl_LIBRARY "opengl32") @@ -111,6 +111,8 @@ if(SDL12TESTS) # Turn off MSVC's aggressive C runtime warnings for the old test programs. if(MSVC) set_target_properties(${_NAME} PROPERTIES COMPILE_DEFINITIONS "${HAVE_OPENGL_DEFINE};_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE") + elseif(APPLE) + set_target_properties(${_NAME} PROPERTIES COMPILE_DEFINITIONS "${HAVE_OPENGL_DEFINE};GL_SILENCE_DEPRECATION=1") else() set_target_properties(${_NAME} PROPERTIES COMPILE_DEFINITIONS "${HAVE_OPENGL_DEFINE}") endif() @@ -149,12 +151,9 @@ if(SDL12TESTS) test_program(testwm "test/testwm.c") test_program(threadwin "test/threadwin.c") test_program(torturethread "test/torturethread.c") - - if(OpenGL_FOUND) - test_program(testdyngl "test/testdyngl.c") - - # testgl links directly to OpenGL (yuck), whereas testdyngl doesn't. - test_program(testgl "test/testgl.c") + test_program(testdyngl "test/testdyngl.c") + test_program(testgl "test/testgl.c") + if(OPENGL_FOUND) if(CMAKE_VERSION VERSION_LESS 3.10) target_link_libraries(testgl ${OPENGL_gl_LIBRARY}) else() @@ -162,10 +161,6 @@ if(SDL12TESTS) endif() endif() - if(APPLE) - set_target_properties(testgl PROPERTIES COMPILE_DEFINITIONS "GL_SILENCE_DEPRECATION=1") - endif() - foreach(fname "icon.bmp" "moose.dat" "picture.xbm" "sail.bmp" "sample.bmp" "sample.wav" "utf8.txt") file(COPY "${CMAKE_SOURCE_DIR}/test/${fname}" DESTINATION "${CMAKE_BINARY_DIR}") endforeach(fname) From 70907e8168cccad62f4e983dcfd0dd9a2be0321c Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Mon, 14 Jun 2021 01:40:10 +0300 Subject: [PATCH 066/606] cmake: Specify ARCHIVE and RUNTIME destinations for INSTALL Fixes: https://github.com/libsdl-org/sdl12-compat/issues/85 --- CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7139f96f3..f7f0169d7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -168,6 +168,8 @@ endif() install(TARGETS SDL LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ) if(SDL12DEVEL) From d2d8f9261d4e5afd00f2af394d4e64aa813ef09b Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Mon, 14 Jun 2021 03:01:10 +0300 Subject: [PATCH 067/606] cmake: attempt to fix the stupid OPENGL_FOUND issue --- CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index f7f0169d7..ff38cc46b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -96,6 +96,9 @@ if(SDL12TESTS) endif() find_package(OpenGL COMPONENTS OpenGL) + if(OpenGL_FOUND) + set(OPENGL_FOUND 1) + endif() if(OPENGL_FOUND) set(HAVE_OPENGL_DEFINE "HAVE_OPENGL") if(WIN32) From f227a5a0da8a6ab12d8365ad4024067bfc28d270 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Mon, 14 Jun 2021 03:10:20 +0300 Subject: [PATCH 068/606] cmake: attempt to fix the stupid osx opengl linkage issue (again.) --- CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ff38cc46b..7d4d6f1f5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -96,14 +96,14 @@ if(SDL12TESTS) endif() find_package(OpenGL COMPONENTS OpenGL) - if(OpenGL_FOUND) - set(OPENGL_FOUND 1) - endif() if(OPENGL_FOUND) set(HAVE_OPENGL_DEFINE "HAVE_OPENGL") if(WIN32) set(OPENGL_gl_LIBRARY "opengl32") set(OPENGL_opengl_LIBRARY "opengl32") + elseif(APPLE) + set(OPENGL_gl_LIBRARY "-Wl,-framework,OpenGL") + set(OPENGL_opengl_LIBRARY "-Wl,-framework,OpenGL") endif() endif() From 31bfd0b525164431593caec4b9000088bf85a3ee Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Mon, 14 Jun 2021 05:11:56 +0300 Subject: [PATCH 069/606] cmake: target-specific flags for sdl-config and sdl.pc. Also do not install them for MSVC. Closes: https://github.com/libsdl-org/sdl12-compat/issues/107 --- CMakeLists.txt | 50 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 17 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7d4d6f1f5..153784191 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -178,27 +178,43 @@ install(TARGETS SDL if(SDL12DEVEL) set(SDL_VERSION "${SDL12_COMPAT_VERSION_STR}") - # FIXME: Make the following target-specific!! - set(SDL_CFLAGS "-D_GNU_SOURCE=1 -D_REENTRANT") - set(SDL_RLD_FLAGS "") # !!! FIXME: this forces rpath, which we might want? - set(SDL_LIBS "-lSDL") - set(SDL_STATIC_LIBS "-lm -ldl -lpthread") - install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} ) - configure_file(sdl12_compat.pc.in sdl12_compat.pc @ONLY) - install(FILES ${CMAKE_BINARY_DIR}/sdl12_compat.pc - DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig - ) - # !!! FIXME: do we _want_ static builds? - set(ENABLE_STATIC_TRUE "") - set(ENABLE_STATIC_FALSE "#") - set(ENABLE_SHARED_TRUE "") - set(ENABLE_SHARED_FALSE "#") + if(NOT MSVC) + if(WIN32) + # FIXME: no SDL_main for Windows! + set(SDL_CFLAGS "") # -Dmain=SDL_main + set(SDL_RLD_FLAGS "") + set(SDL_LIBS "-mwindows -lSDL") # -mwindows -lmingw32 -lSDLmain -lSDL + set(SDL_STATIC_LIBS "-lkernel32 -luser32") # -mwindows -lmingw32 -lSDLmain -lSDL -lkernel32 -luser32 + elseif(APPLE) + # FIXME: no SDL_main for Mac! + set(SDL_CFLAGS "-D_THREAD_SAFE") # -Dmain=SDL_main + set(SDL_LIBS "-lSDL") # -lSDLmain + set(SDL_STATIC_LIBS "-Wl,-framework,AppKit -lobjc") + set(SDL_RLD_FLAGS "") # !!! FIXME: this forces rpath, which we might want? + else() # unix + set(SDL_CFLAGS "-D_GNU_SOURCE=1 -D_REENTRANT") + set(SDL_RLD_FLAGS "") # !!! FIXME: this forces rpath, which we might want? + set(SDL_LIBS "-lSDL") + set(SDL_STATIC_LIBS "-lm -ldl -lpthread") + endif() - configure_file("${CMAKE_SOURCE_DIR}/sdl-config.in" "${CMAKE_BINARY_DIR}/sdl-config" @ONLY) - install(PROGRAMS "${CMAKE_BINARY_DIR}/sdl-config" DESTINATION bin) + configure_file(sdl12_compat.pc.in sdl12_compat.pc @ONLY) + install(FILES ${CMAKE_BINARY_DIR}/sdl12_compat.pc + DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig + ) + + # !!! FIXME: do we _want_ static builds? + set(ENABLE_STATIC_TRUE "") + set(ENABLE_STATIC_FALSE "#") + set(ENABLE_SHARED_TRUE "") + set(ENABLE_SHARED_FALSE "#") + + configure_file("${CMAKE_SOURCE_DIR}/sdl-config.in" "${CMAKE_BINARY_DIR}/sdl-config" @ONLY) + install(PROGRAMS "${CMAKE_BINARY_DIR}/sdl-config" DESTINATION bin) + endif() set(SOEXT ${CMAKE_SHARED_LIBRARY_SUFFIX}) get_target_property(SONAME SDL OUTPUT_NAME) From 103df6b0eb68d85f9b320bf5d4061c622f1a9eea Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Mon, 14 Jun 2021 06:10:32 +0300 Subject: [PATCH 070/606] cmake: allow static builds only with Linux, error out otherwise. also don't set SDL_STATIC_LIBS if not building static a lib. Closes: https://github.com/libsdl-org/sdl12-compat/issues/108 --- CMakeLists.txt | 57 +++++++++++++++++++------------------------------- 1 file changed, 21 insertions(+), 36 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 153784191..45d842f3b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,6 +13,10 @@ option(SDL12TESTS "Enable to build SDL-1.2 test programs" ON) option(SDL12DEVEL "Enable installing SDL-1.2 development headers" ON) option(STATICDEVEL "Enable installing static link library" OFF) +if(STATICDEVEL AND NOT (CMAKE_SYSTEM_NAME MATCHES "Linux")) + MESSAGE(FATAL_ERROR "Static builds are only supported on Linux.") +endif() + set(CMAKE_SKIP_RPATH TRUE) if(APPLE) @@ -178,27 +182,29 @@ install(TARGETS SDL if(SDL12DEVEL) set(SDL_VERSION "${SDL12_COMPAT_VERSION_STR}") - install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} - ) + install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) if(NOT MSVC) if(WIN32) # FIXME: no SDL_main for Windows! set(SDL_CFLAGS "") # -Dmain=SDL_main set(SDL_RLD_FLAGS "") - set(SDL_LIBS "-mwindows -lSDL") # -mwindows -lmingw32 -lSDLmain -lSDL - set(SDL_STATIC_LIBS "-lkernel32 -luser32") # -mwindows -lmingw32 -lSDLmain -lSDL -lkernel32 -luser32 + set(SDL_LIBS "-lSDL -mwindows") # -lmingw32 -lSDLmain -lSDL -mwindows + set(SDL_STATIC_LIBS "") elseif(APPLE) # FIXME: no SDL_main for Mac! set(SDL_CFLAGS "-D_THREAD_SAFE") # -Dmain=SDL_main set(SDL_LIBS "-lSDL") # -lSDLmain - set(SDL_STATIC_LIBS "-Wl,-framework,AppKit -lobjc") + set(SDL_STATIC_LIBS "") set(SDL_RLD_FLAGS "") # !!! FIXME: this forces rpath, which we might want? else() # unix set(SDL_CFLAGS "-D_GNU_SOURCE=1 -D_REENTRANT") set(SDL_RLD_FLAGS "") # !!! FIXME: this forces rpath, which we might want? set(SDL_LIBS "-lSDL") set(SDL_STATIC_LIBS "-lm -ldl -lpthread") + if(NOT STATICDEVEL) + set(SDL_STATIC_LIBS "") + endif() endif() configure_file(sdl12_compat.pc.in sdl12_compat.pc @ONLY) @@ -207,8 +213,13 @@ if(SDL12DEVEL) ) # !!! FIXME: do we _want_ static builds? - set(ENABLE_STATIC_TRUE "") - set(ENABLE_STATIC_FALSE "#") + if(STATICDEVEL) + set(ENABLE_STATIC_TRUE "") + set(ENABLE_STATIC_FALSE "#") + else() + set(ENABLE_STATIC_TRUE "#") + set(ENABLE_STATIC_FALSE "") + endif() set(ENABLE_SHARED_TRUE "") set(ENABLE_SHARED_FALSE "#") @@ -232,37 +243,11 @@ endif() if(STATICDEVEL AND SDL12DEVEL) add_library(SDL-static STATIC ${SDL12COMPAT_SRCS}) target_include_directories(SDL-static PRIVATE ${SDL2_INCLUDE_DIRS}) - if(UNIX AND NOT APPLE) - set_target_properties(SDL-static PROPERTIES COMPILE_DEFINITIONS "_REENTRANT") - target_link_libraries(SDL-static PRIVATE dl) - endif() - if(APPLE) - set_target_properties(SDL-static PROPERTIES COMPILE_DEFINITIONS "_THREAD_SAFE") - target_link_libraries(SDL-static PRIVATE "-framework AppKit") - set_target_properties(SDL-static PROPERTIES - MACOSX_RPATH 1 - OUTPUT_NAME "SDL" - ) - else() - set_target_properties(SDL-static PROPERTIES + set_target_properties(SDL-static PROPERTIES COMPILE_DEFINITIONS "_REENTRANT") + target_link_libraries(SDL-static PRIVATE dl) + set_target_properties(SDL-static PROPERTIES VERSION "${SDL12_COMPAT_VERSION_STR}" OUTPUT_NAME "SDL") - endif() - - if(MINGW) - set_target_properties(SDL-static PROPERTIES LINK_FLAGS "-nostdlib") - endif() - if(MSVC) - # Don't try to link with the default set of libraries. - set_target_properties(SDL-static PROPERTIES COMPILE_FLAGS "/GS-") - set_target_properties(SDL-static PROPERTIES LINK_FLAGS "/NODEFAULTLIB") - # Make sure /RTC1 is disabled: (from SDL2 CMake) - foreach(flag_var - CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE - CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO) - string(REGEX REPLACE "/RTC(su|[1su])" "" ${flag_var} "${${flag_var}}") - endforeach(flag_var) - endif() install(TARGETS SDL-static ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} From d8019a1fedad67d90aed74fac2ee0660389e3043 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Mon, 14 Jun 2021 14:00:50 +0300 Subject: [PATCH 071/606] comment out Libs.private entry if not building a static library. --- CMakeLists.txt | 10 +++++----- sdl12_compat.pc.in | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 45d842f3b..ea181a91f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -207,11 +207,6 @@ if(SDL12DEVEL) endif() endif() - configure_file(sdl12_compat.pc.in sdl12_compat.pc @ONLY) - install(FILES ${CMAKE_BINARY_DIR}/sdl12_compat.pc - DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig - ) - # !!! FIXME: do we _want_ static builds? if(STATICDEVEL) set(ENABLE_STATIC_TRUE "") @@ -223,6 +218,11 @@ if(SDL12DEVEL) set(ENABLE_SHARED_TRUE "") set(ENABLE_SHARED_FALSE "#") + configure_file(sdl12_compat.pc.in sdl12_compat.pc @ONLY) + install(FILES ${CMAKE_BINARY_DIR}/sdl12_compat.pc + DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig + ) + configure_file("${CMAKE_SOURCE_DIR}/sdl-config.in" "${CMAKE_BINARY_DIR}/sdl-config" @ONLY) install(PROGRAMS "${CMAKE_BINARY_DIR}/sdl-config" DESTINATION bin) endif() diff --git a/sdl12_compat.pc.in b/sdl12_compat.pc.in index 39e5c3117..d5dac574e 100644 --- a/sdl12_compat.pc.in +++ b/sdl12_compat.pc.in @@ -10,5 +10,5 @@ Description: An SDL-1.2 compatibility layer that uses SDL 2.0 behind the scenes. Version: @PROJECT_VERSION@ Provides: sdl = @SDL_VERSION@ Libs: -L${libdir} @SDL_RLD_FLAGS@ @SDL_LIBS@ -Libs.private: -L${libdir} @SDL_LIBS@ @SDL_STATIC_LIBS@ +@ENABLE_STATIC_TRUE@Libs.private: -L${libdir} @SDL_LIBS@ @SDL_STATIC_LIBS@ Cflags: -I${includedir}/SDL @SDL_CFLAGS@ From c5bd71de527b981ec736dbd94e973cc11de0cbc0 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Mon, 14 Jun 2021 14:01:20 +0300 Subject: [PATCH 072/606] fixed build against SDL2 versions older than 2.0.14 See: https://github.com/libsdl-org/sdl12-compat/issues/52#issuecomment-856782485 --- src/SDL12_compat.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index c36de9d45..a3c3d3a90 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -3940,6 +3940,9 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12) bpp = SDL_BITSPERPIXEL(dmode.format); } + #if !SDL_VERSION_ATLEAST(2,0,14) + #define SDL_PIXELFORMAT_XRGB8888 SDL_PIXELFORMAT_RGB888 + #endif switch (bpp) { case 8: appfmt = SDL_PIXELFORMAT_INDEX8; break; case 16: appfmt = SDL_PIXELFORMAT_RGB565; FIXME("bgr instead of rgb?"); break; From d1f3c6e70917c4f36e6f5f78bfb80a0fb473e9f6 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Tue, 15 Jun 2021 11:50:02 +0300 Subject: [PATCH 073/606] fix linkage of MSVC x86 builds with /NODUFALTLIB after fake-cdrom code. see https://github.com/libsdl-org/sdl12-compat/issues/32 --- CMakeLists.txt | 13 +- src/Makefile.vc | 7 + src/SDL12_compat.c | 4 + src/x86_msvc.h | 656 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 679 insertions(+), 1 deletion(-) create mode 100644 src/x86_msvc.h diff --git a/CMakeLists.txt b/CMakeLists.txt index ea181a91f..874f89fc7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -38,6 +38,8 @@ set(SDL12COMPAT_SRCS ) add_library(SDL SHARED ${SDL12COMPAT_SRCS}) +include(CheckCSourceCompiles) + include(GNUInstallDirs) include("cmake/modules/FindSDL2.cmake") target_include_directories(SDL PRIVATE ${SDL2_INCLUDE_DIRS}) @@ -83,7 +85,16 @@ if(MINGW) endif() if(MSVC) # Don't try to link with the default set of libraries. - set_target_properties(SDL PROPERTIES COMPILE_FLAGS "/GS-") + set(MSVC_FLAGS "/GS-") + check_c_source_compiles("int main(void) { +#ifndef _M_IX86 +#error not x86 +#endif +return 0; }" IS_X86) + if(IS_X86) # don't emit SSE2 in x86 builds + set(MSVC_FLAGS "${MSVC_FLAGS} /arch:SSE") + endif() + set_target_properties(SDL PROPERTIES COMPILE_FLAGS ${MSVC_FLAGS}) set_target_properties(SDL PROPERTIES LINK_FLAGS "/NODEFAULTLIB") # Make sure /RTC1 is disabled: (from SDL2 CMake) foreach(flag_var diff --git a/src/Makefile.vc b/src/Makefile.vc index bdfe1428d..8a2cd8e12 100644 --- a/src/Makefile.vc +++ b/src/Makefile.vc @@ -1,5 +1,8 @@ # Makefile for Win32 using MSVC: # nmake /f Makefile.vc +# +# If you specifically want to build for x86: +# nmake /f Makefile.vc CPU=x86 # change INCLUDES so it points to SDL2 headers directory: INCLUDES = -Iinclude @@ -14,6 +17,10 @@ CFLAGS = /nologo /O2 /MD /W3 /GS- LDFLAGS = /nologo /DLL /NODEFAULTLIB /RELEASE LDLIBS = kernel32.lib user32.lib +!if "$(CPU)" == "x86" +CFLAGS = $(CFLAGS) /arch:SSE +!endif + DLLNAME = SDL.dll IMPNAME = SDL.lib diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index a3c3d3a90..17b536e5e 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -5940,6 +5940,10 @@ SDL_LoadWAV_RW(SDL12_RWops *rwops12, int freerwops12, an audio CD-ROM, and will decode these files and mix them into an audio stream as if they were playing from a disc. */ +#if defined(_MSC_VER) && defined(_M_IX86) +#include "x86_msvc.h" +#endif + #define CDAUDIO_FPS 75 /* CD audio frames per second. */ /* public domain, single-header MP3 decoder for fake CD-ROM audio support! */ diff --git a/src/x86_msvc.h b/src/x86_msvc.h new file mode 100644 index 000000000..997d5a96f --- /dev/null +++ b/src/x86_msvc.h @@ -0,0 +1,656 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2021 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/* taken from SDL_stdlib.c of SDL2 */ + +/* *INDENT-OFF* */ + +/* Float to long */ +void +__declspec(naked) +_ftol() +{ + __asm { + push ebp + mov ebp,esp + sub esp,20h + and esp,0FFFFFFF0h + fld st(0) + fst dword ptr [esp+18h] + fistp qword ptr [esp+10h] + fild qword ptr [esp+10h] + mov edx,dword ptr [esp+18h] + mov eax,dword ptr [esp+10h] + test eax,eax + je integer_QnaN_or_zero +arg_is_not_integer_QnaN: + fsubp st(1),st + test edx,edx + jns positive + fstp dword ptr [esp] + mov ecx,dword ptr [esp] + xor ecx,80000000h + add ecx,7FFFFFFFh + adc eax,0 + mov edx,dword ptr [esp+14h] + adc edx,0 + jmp localexit +positive: + fstp dword ptr [esp] + mov ecx,dword ptr [esp] + add ecx,7FFFFFFFh + sbb eax,0 + mov edx,dword ptr [esp+14h] + sbb edx,0 + jmp localexit +integer_QnaN_or_zero: + mov edx,dword ptr [esp+14h] + test edx,7FFFFFFFh + jne arg_is_not_integer_QnaN + fstp dword ptr [esp+18h] + fstp dword ptr [esp+18h] +localexit: + leave + ret + } +} + +void +_ftol2() +{ + _ftol(); +} + +void +_ftol2_sse() +{ + _ftol(); +} + +/* 64-bit math operators for 32-bit systems */ +void +__declspec(naked) +_allmul() +{ + __asm { + mov eax, dword ptr[esp+8] + mov ecx, dword ptr[esp+10h] + or ecx, eax + mov ecx, dword ptr[esp+0Ch] + jne hard + mov eax, dword ptr[esp+4] + mul ecx + ret 10h +hard: + push ebx + mul ecx + mov ebx, eax + mov eax, dword ptr[esp+8] + mul dword ptr[esp+14h] + add ebx, eax + mov eax, dword ptr[esp+8] + mul ecx + add edx, ebx + pop ebx + ret 10h + } +} + +void +__declspec(naked) +_alldiv() +{ + __asm { + push edi + push esi + push ebx + xor edi,edi + mov eax,dword ptr [esp+14h] + or eax,eax + jge L1 + inc edi + mov edx,dword ptr [esp+10h] + neg eax + neg edx + sbb eax,0 + mov dword ptr [esp+14h],eax + mov dword ptr [esp+10h],edx +L1: + mov eax,dword ptr [esp+1Ch] + or eax,eax + jge L2 + inc edi + mov edx,dword ptr [esp+18h] + neg eax + neg edx + sbb eax,0 + mov dword ptr [esp+1Ch],eax + mov dword ptr [esp+18h],edx +L2: + or eax,eax + jne L3 + mov ecx,dword ptr [esp+18h] + mov eax,dword ptr [esp+14h] + xor edx,edx + div ecx + mov ebx,eax + mov eax,dword ptr [esp+10h] + div ecx + mov edx,ebx + jmp L4 +L3: + mov ebx,eax + mov ecx,dword ptr [esp+18h] + mov edx,dword ptr [esp+14h] + mov eax,dword ptr [esp+10h] +L5: + shr ebx,1 + rcr ecx,1 + shr edx,1 + rcr eax,1 + or ebx,ebx + jne L5 + div ecx + mov esi,eax + mul dword ptr [esp+1Ch] + mov ecx,eax + mov eax,dword ptr [esp+18h] + mul esi + add edx,ecx + jb L6 + cmp edx,dword ptr [esp+14h] + ja L6 + jb L7 + cmp eax,dword ptr [esp+10h] + jbe L7 +L6: + dec esi +L7: + xor edx,edx + mov eax,esi +L4: + dec edi + jne L8 + neg edx + neg eax + sbb edx,0 +L8: + pop ebx + pop esi + pop edi + ret 10h + } +} + +void +__declspec(naked) +_aulldiv() +{ + __asm { + push ebx + push esi + mov eax,dword ptr [esp+18h] + or eax,eax + jne L1 + mov ecx,dword ptr [esp+14h] + mov eax,dword ptr [esp+10h] + xor edx,edx + div ecx + mov ebx,eax + mov eax,dword ptr [esp+0Ch] + div ecx + mov edx,ebx + jmp L2 +L1: + mov ecx,eax + mov ebx,dword ptr [esp+14h] + mov edx,dword ptr [esp+10h] + mov eax,dword ptr [esp+0Ch] +L3: + shr ecx,1 + rcr ebx,1 + shr edx,1 + rcr eax,1 + or ecx,ecx + jne L3 + div ebx + mov esi,eax + mul dword ptr [esp+18h] + mov ecx,eax + mov eax,dword ptr [esp+14h] + mul esi + add edx,ecx + jb L4 + cmp edx,dword ptr [esp+10h] + ja L4 + jb L5 + cmp eax,dword ptr [esp+0Ch] + jbe L5 +L4: + dec esi +L5: + xor edx,edx + mov eax,esi +L2: + pop esi + pop ebx + ret 10h + } +} + +void +__declspec(naked) +_allrem() +{ + __asm { + push ebx + push edi + xor edi,edi + mov eax,dword ptr [esp+10h] + or eax,eax + jge L1 + inc edi + mov edx,dword ptr [esp+0Ch] + neg eax + neg edx + sbb eax,0 + mov dword ptr [esp+10h],eax + mov dword ptr [esp+0Ch],edx +L1: + mov eax,dword ptr [esp+18h] + or eax,eax + jge L2 + mov edx,dword ptr [esp+14h] + neg eax + neg edx + sbb eax,0 + mov dword ptr [esp+18h],eax + mov dword ptr [esp+14h],edx +L2: + or eax,eax + jne L3 + mov ecx,dword ptr [esp+14h] + mov eax,dword ptr [esp+10h] + xor edx,edx + div ecx + mov eax,dword ptr [esp+0Ch] + div ecx + mov eax,edx + xor edx,edx + dec edi + jns L4 + jmp L8 +L3: + mov ebx,eax + mov ecx,dword ptr [esp+14h] + mov edx,dword ptr [esp+10h] + mov eax,dword ptr [esp+0Ch] +L5: + shr ebx,1 + rcr ecx,1 + shr edx,1 + rcr eax,1 + or ebx,ebx + jne L5 + div ecx + mov ecx,eax + mul dword ptr [esp+18h] + xchg eax,ecx + mul dword ptr [esp+14h] + add edx,ecx + jb L6 + cmp edx,dword ptr [esp+10h] + ja L6 + jb L7 + cmp eax,dword ptr [esp+0Ch] + jbe L7 +L6: + sub eax,dword ptr [esp+14h] + sbb edx,dword ptr [esp+18h] +L7: + sub eax,dword ptr [esp+0Ch] + sbb edx,dword ptr [esp+10h] + dec edi + jns L8 +L4: + neg edx + neg eax + sbb edx,0 +L8: + pop edi + pop ebx + ret 10h + } +} + +void +__declspec(naked) +_aullrem() +{ + __asm { + push ebx + mov eax,dword ptr [esp+14h] + or eax,eax + jne L1 + mov ecx,dword ptr [esp+10h] + mov eax,dword ptr [esp+0Ch] + xor edx,edx + div ecx + mov eax,dword ptr [esp+8] + div ecx + mov eax,edx + xor edx,edx + jmp L2 +L1: + mov ecx,eax + mov ebx,dword ptr [esp+10h] + mov edx,dword ptr [esp+0Ch] + mov eax,dword ptr [esp+8] +L3: + shr ecx,1 + rcr ebx,1 + shr edx,1 + rcr eax,1 + or ecx,ecx + jne L3 + div ebx + mov ecx,eax + mul dword ptr [esp+14h] + xchg eax,ecx + mul dword ptr [esp+10h] + add edx,ecx + jb L4 + cmp edx,dword ptr [esp+0Ch] + ja L4 + jb L5 + cmp eax,dword ptr [esp+8] + jbe L5 +L4: + sub eax,dword ptr [esp+10h] + sbb edx,dword ptr [esp+14h] +L5: + sub eax,dword ptr [esp+8] + sbb edx,dword ptr [esp+0Ch] + neg edx + neg eax + sbb edx,0 +L2: + pop ebx + ret 10h + } +} + +void +__declspec(naked) +_alldvrm() +{ + __asm { + push edi + push esi + push ebp + xor edi,edi + xor ebp,ebp + mov eax,dword ptr [esp+14h] + or eax,eax + jge L1 + inc edi + inc ebp + mov edx,dword ptr [esp+10h] + neg eax + neg edx + sbb eax,0 + mov dword ptr [esp+14h],eax + mov dword ptr [esp+10h],edx +L1: + mov eax,dword ptr [esp+1Ch] + or eax,eax + jge L2 + inc edi + mov edx,dword ptr [esp+18h] + neg eax + neg edx + sbb eax,0 + mov dword ptr [esp+1Ch],eax + mov dword ptr [esp+18h],edx +L2: + or eax,eax + jne L3 + mov ecx,dword ptr [esp+18h] + mov eax,dword ptr [esp+14h] + xor edx,edx + div ecx + mov ebx,eax + mov eax,dword ptr [esp+10h] + div ecx + mov esi,eax + mov eax,ebx + mul dword ptr [esp+18h] + mov ecx,eax + mov eax,esi + mul dword ptr [esp+18h] + add edx,ecx + jmp L4 +L3: + mov ebx,eax + mov ecx,dword ptr [esp+18h] + mov edx,dword ptr [esp+14h] + mov eax,dword ptr [esp+10h] +L5: + shr ebx,1 + rcr ecx,1 + shr edx,1 + rcr eax,1 + or ebx,ebx + jne L5 + div ecx + mov esi,eax + mul dword ptr [esp+1Ch] + mov ecx,eax + mov eax,dword ptr [esp+18h] + mul esi + add edx,ecx + jb L6 + cmp edx,dword ptr [esp+14h] + ja L6 + jb L7 + cmp eax,dword ptr [esp+10h] + jbe L7 +L6: + dec esi + sub eax,dword ptr [esp+18h] + sbb edx,dword ptr [esp+1Ch] +L7: + xor ebx,ebx +L4: + sub eax,dword ptr [esp+10h] + sbb edx,dword ptr [esp+14h] + dec ebp + jns L9 + neg edx + neg eax + sbb edx,0 +L9: + mov ecx,edx + mov edx,ebx + mov ebx,ecx + mov ecx,eax + mov eax,esi + dec edi + jne L8 + neg edx + neg eax + sbb edx,0 +L8: + pop ebp + pop esi + pop edi + ret 10h + } +} + +void +__declspec(naked) +_aulldvrm() +{ + __asm { + push esi + mov eax,dword ptr [esp+14h] + or eax,eax + jne L1 + mov ecx,dword ptr [esp+10h] + mov eax,dword ptr [esp+0Ch] + xor edx,edx + div ecx + mov ebx,eax + mov eax,dword ptr [esp+8] + div ecx + mov esi,eax + mov eax,ebx + mul dword ptr [esp+10h] + mov ecx,eax + mov eax,esi + mul dword ptr [esp+10h] + add edx,ecx + jmp L2 +L1: + mov ecx,eax + mov ebx,dword ptr [esp+10h] + mov edx,dword ptr [esp+0Ch] + mov eax,dword ptr [esp+8] +L3: + shr ecx,1 + rcr ebx,1 + shr edx,1 + rcr eax,1 + or ecx,ecx + jne L3 + div ebx + mov esi,eax + mul dword ptr [esp+14h] + mov ecx,eax + mov eax,dword ptr [esp+10h] + mul esi + add edx,ecx + jb L4 + cmp edx,dword ptr [esp+0Ch] + ja L4 + jb L5 + cmp eax,dword ptr [esp+8] + jbe L5 +L4: + dec esi + sub eax,dword ptr [esp+10h] + sbb edx,dword ptr [esp+14h] +L5: + xor ebx,ebx +L2: + sub eax,dword ptr [esp+8] + sbb edx,dword ptr [esp+0Ch] + neg edx + neg eax + sbb edx,0 + mov ecx,edx + mov edx,ebx + mov ebx,ecx + mov ecx,eax + mov eax,esi + pop esi + ret 10h + } +} + +void +__declspec(naked) +_allshl() +{ + __asm { + cmp cl,40h + jae RETZERO + cmp cl,20h + jae MORE32 + shld edx,eax,cl + shl eax,cl + ret +MORE32: + mov edx,eax + xor eax,eax + and cl,1Fh + shl edx,cl + ret +RETZERO: + xor eax,eax + xor edx,edx + ret + } +} + +void +__declspec(naked) +_allshr() +{ + __asm { + cmp cl,3Fh + jae RETSIGN + cmp cl,20h + jae MORE32 + shrd eax,edx,cl + sar edx,cl + ret +MORE32: + mov eax,edx + sar edx,1Fh + and cl,1Fh + sar eax,cl + ret +RETSIGN: + sar edx,1Fh + mov eax,edx + ret + } +} + +void +__declspec(naked) +_aullshr() +{ + __asm { + cmp cl,40h + jae RETZERO + cmp cl,20h + jae MORE32 + shrd eax,edx,cl + shr edx,cl + ret +MORE32: + mov eax,edx + xor edx,edx + and cl,1Fh + shr eax,cl + ret +RETZERO: + xor eax,eax + xor edx,edx + ret + } +} +/* *INDENT-ON* */ + +/* vi: set ts=4 sw=4 expandtab: */ From 0d11cbf7a25861d07380cd14177d1b66abef9117 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Tue, 15 Jun 2021 11:55:02 +0300 Subject: [PATCH 074/606] RWops12to20_size: remove the useless Sint64 cast on size Closes: https://github.com/libsdl-org/sdl12-compat/issues/109 --- src/SDL12_compat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 17b536e5e..e17c1b5b3 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -5809,7 +5809,7 @@ RWops12to20_size(struct SDL_RWops *rwops20) if (pos == -1) { return SDL20_Error(SDL_EFSEEK); } - size = (Sint64) rwops12->seek(rwops12, 0, RW_SEEK_END); + size = rwops12->seek(rwops12, 0, RW_SEEK_END); rwops12->seek(rwops12, pos, RW_SEEK_SET); rwops20->hidden.unknown.data2 = (void *) ((size_t) size); return size; From 7c391e4783fae5b58a5e18ae8116148c144e77b0 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Tue, 15 Jun 2021 12:29:20 +0300 Subject: [PATCH 075/606] always define DRMP3_API -- just in case. --- src/SDL12_compat.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index e17c1b5b3..f8c6f104c 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -5953,6 +5953,8 @@ SDL_LoadWAV_RW(SDL12_RWops *rwops12, int freerwops12, #define DRMP3_API __attribute__((visibility("hidden"))) #elif defined(__APPLE__) #define DRMP3_API __private_extern__ +#else +#define DRMP3_API /* just in case */ #endif #define DR_MP3_NO_STDIO 1 #define DR_MP3_NO_S16 1 From d4f99d4f19e42fbe1f205278f35e4ad5c95bf0d8 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Tue, 15 Jun 2021 23:20:02 +0300 Subject: [PATCH 076/606] comment out drmp3_exp, drmp3_sin and drmp3_cos inlines and math.h header they aren't used. --- src/dr_mp3.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/dr_mp3.h b/src/dr_mp3.h index 9e61bdfa6..b2e20f0af 100644 --- a/src/dr_mp3.h +++ b/src/dr_mp3.h @@ -2389,7 +2389,9 @@ DRMP3_API void drmp3dec_f32_to_s16(const float *in, drmp3_int16 *out, size_t num Main Public API ************************************************************************************************************************************************************/ +#if 0 /* not used. */ #include /* For sin() and exp(). */ +#endif #if defined(SIZE_MAX) #define DRMP3_SIZE_MAX SIZE_MAX @@ -2476,7 +2478,7 @@ static DRMP3_INLINE drmp3_uint32 drmp3_gcf_u32(drmp3_uint32 a, drmp3_uint32 b) return a; } - +#if 0 /* not used. */ static DRMP3_INLINE double drmp3_sin(double x) { /* TODO: Implement custom sin(x). */ @@ -2493,7 +2495,7 @@ static DRMP3_INLINE double drmp3_cos(double x) { return drmp3_sin((DRMP3_PI_D*0.5) - x); } - +#endif static void* drmp3__malloc_default(size_t sz, void* pUserData) { From 7677b7ae855eb4eaf67d47db80bf7b30b90a7558 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Tue, 15 Jun 2021 23:20:24 +0300 Subject: [PATCH 077/606] cmake: remove -lm and -lpthread from unix SDL_STATIC_LIBS: sdl12-compat doesn't use them. only -ldl is needed. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 874f89fc7..f5587dfd8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -212,7 +212,7 @@ if(SDL12DEVEL) set(SDL_CFLAGS "-D_GNU_SOURCE=1 -D_REENTRANT") set(SDL_RLD_FLAGS "") # !!! FIXME: this forces rpath, which we might want? set(SDL_LIBS "-lSDL") - set(SDL_STATIC_LIBS "-lm -ldl -lpthread") + set(SDL_STATIC_LIBS "-ldl") if(NOT STATICDEVEL) set(SDL_STATIC_LIBS "") endif() From 6b2d3dfcdc49da5d46666eedfe1f01251c23acf4 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 17 Jun 2021 10:57:07 -0400 Subject: [PATCH 078/606] The SDL2 "dummy" video driver reports a vidmode of 0x0, so don't assert on it. --- src/SDL12_compat.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index f8c6f104c..224a87b48 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1517,10 +1517,11 @@ Init12VidModes(void) if (SDL20_GetDisplayMode(VideoDisplayIndex, i, &mode) < 0) { continue; } - if (!mode.w || !mode.h) { - SDL_assert(0 && "Can this actually happen?"); + + if ((mode.w <= 0) || (mode.h <= 0)) { continue; } + if (mode.w > 65535 || mode.h > 65535) { continue; /* can't fit to 16-bits for SDL12_Rect */ } From 30c4444df0f0b84a8ed50a02c16f611cf7106bf5 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 17 Jun 2021 19:21:44 -0400 Subject: [PATCH 079/606] Reworked the FIXME stuff. Now it can be set to preprocess out FIXMEs entirely, or make them only display when using an environment variable, or refuse to build outright if a FIXME still exists. This way we can choose to ignore them all, or only see them when developers need info, or eventually make sure we don't have any pending TODOs left. --- src/SDL12_compat.c | 46 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 224a87b48..8734e7d12 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -57,17 +57,28 @@ extern "C" { #endif -#if 0 -#define FIXME(x) do {} while (0) +#define ENABLE_FIXMES 1 +#if ENABLE_FIXMES == -1 /* don't even allow a build to finish if there's a FIXME */ + /* the goal with this nonsense is to make the compiler print an error that + broadcasts the problem _and the string literal_ from the actual FIXME line */ + extern void YouCannotBuildUntilYouResolveThisFixme(char *x); + #define FIXME(x) YouCannotBuildUntilYouResolveThisFixme(-->) +#elif ENABLE_FIXMES == 0 /* compile out any FIXMEs entirely. */ + #define FIXME(x) do {} while (0) +#elif ENABLE_FIXMES == 1 /* Log a warning the first time a FIXME is executed. */ + static SDL_bool PrintFixmes = SDL_TRUE; + #define FIXME(x) \ + do { \ + if (PrintFixmes) { \ + static SDL_bool seen = SDL_FALSE; \ + if (!seen) { \ + SDL20_Log("FIXME: %s (%s:%d)\n", x, __FUNCTION__, __LINE__); \ + seen = SDL_TRUE; \ + } \ + } \ + } while (0) #else -#define FIXME(x) \ - do { \ - static SDL_bool seen = SDL_FALSE; \ - if (!seen) { \ - SDL20_Log("FIXME: %s (%s:%d)\n", x, __FUNCTION__, __LINE__); \ - seen = SDL_TRUE; \ - } \ - } while (0) + #error Please fix the ENABLE_FIXMES define. #endif #define SDL20_SYM(rc,fn,params,args,ret) \ @@ -1032,11 +1043,18 @@ LoadSDL20(void) if (!okay) { sprintf_fn(loaderror, "SDL2 %d.%d.%d library is too old.", v.major, v.minor, v.patch); } else { - #if defined(__DATE__) && defined(__TIME__) - SDL20_Log("sdl12-compat, built on " __DATE__ " at " __TIME__ ", talking to SDL2 %d.%d.%d", v.major, v.minor, v.patch); - #else - SDL20_Log("sdl12-compat, talking to SDL2 %d.%d.%d", v.major, v.minor, v.patch); + const char *envr = SDL20_getenv("SDL12_COMPAT_DEBUG_LOGGING"); + const SDL_bool debug_logging = (!envr || (SDL20_atoi(envr) == 0)) ? SDL_FALSE : SDL_TRUE; + #if ENABLE_FIXMES == 1 + PrintFixmes = debug_logging; #endif + if (debug_logging) { + #if defined(__DATE__) && defined(__TIME__) + SDL20_Log("sdl12-compat, built on " __DATE__ " at " __TIME__ ", talking to SDL2 %d.%d.%d", v.major, v.minor, v.patch); + #else + SDL20_Log("sdl12-compat, talking to SDL2 %d.%d.%d", v.major, v.minor, v.patch); + #endif + } } } if (!okay) { From c39259cc9cd2d44321a188035dc613f1a13a1c6c Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 17 Jun 2021 21:29:24 -0400 Subject: [PATCH 080/606] SDL_EnableUNICODE(-1) should query the current state without changing it. --- src/SDL12_compat.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 8734e7d12..da5e61d06 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -5488,12 +5488,14 @@ SDL_GetKeyRepeat(int *delay, int *interval) DECLSPEC int SDLCALL SDL_EnableUNICODE(int enable) { - int old = EnabledUnicode; - EnabledUnicode = enable; - if (enable) { - SDL20_StartTextInput(); - } else { - SDL20_StopTextInput(); + const int old = EnabledUnicode; + if (enable >= 0) { + EnabledUnicode = enable; + if (enable) { + SDL20_StartTextInput(); + } else { + SDL20_StopTextInput(); + } } return old; } From 64a1f3b2eab0a8cc5356c51c65a09ca4db836bd3 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 17 Jun 2021 22:14:20 -0400 Subject: [PATCH 081/606] Use SDL_arraysize() instead of the more-verbose sizeof tapdance. --- src/SDL12_compat.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index da5e61d06..939fe3fdf 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1563,7 +1563,7 @@ Init12VidModes(void) /* Attempt to add all of the fake modes. */ if (use_fake_modes) { - for (j = 0; j < sizeof(fake_modes) / sizeof(fake_modes[0]); ++j) { + for (j = 0; j < SDL_arraysize(fake_modes); ++j) { if (VidModeSizeGreater(&prev_mode, &fake_modes[j]) && VidModeSizeGreater(&fake_modes[j], ¤t_mode)) { if (AddVidModeToList(vmode, &fake_modes[j])) { return SDL20_OutOfMemory(); @@ -1582,7 +1582,7 @@ Init12VidModes(void) /* we need to try to add fake modes to the end of the list once there are no more real modes */ if (use_fake_modes) { - for (i = 0; i < sizeof(fake_modes) / sizeof(fake_modes[0]); ++i) { + for (i = 0; i < SDL_arraysize(fake_modes); ++i) { if (VidModeSizeGreater(&prev_mode, &fake_modes[i])) { if (AddVidModeToList(vmode, &fake_modes[i])) { return SDL20_OutOfMemory(); From bd58633ed55a9e0d4616a827555b6a41ab3dcb26 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 17 Jun 2021 22:58:22 -0400 Subject: [PATCH 082/606] Handle video modes specially for the "dummy" driver. Generally we shouldn't do this for a specific driver, but various unit tests might rely on this specific one, etc. --- src/SDL12_compat.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 939fe3fdf..03b019c55 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -820,6 +820,8 @@ typedef struct OpenGLEntryPoints /* !!! FIXME: grep for VideoWindow20 places that might care if it's NULL */ /* !!! FIXME: go through all of these. */ +static Uint32 LinkedSDL2VersionInt = 0; +static SDL_bool IsDummyVideo = SDL_FALSE; static VideoModeList *VideoModes = NULL; static int VideoModesCount = 0; /* this counts items in VideoModeList, not total video modes. */ static SDL12_VideoInfo VideoInfo12; @@ -1039,7 +1041,8 @@ LoadSDL20(void) if (okay) { SDL_version v; SDL20_GetVersion(&v); - okay = (SDL_VERSIONNUM(v.major,v.minor,v.patch) >= SDL20_REQUIRED_VER); + LinkedSDL2VersionInt = SDL_VERSIONNUM(v.major, v.minor, v.patch); + okay = (LinkedSDL2VersionInt >= SDL20_REQUIRED_VER); if (!okay) { sprintf_fn(loaderror, "SDL2 %d.%d.%d library is too old.", v.major, v.minor, v.patch); } else { @@ -1536,8 +1539,17 @@ Init12VidModes(void) continue; } + if ((mode.w == 0) && (mode.h == 0)) { + /* SDL2 has a bug in its dummy driver before 2.0.16 that causes it to report a bogus video mode. */ + if (IsDummyVideo && (LinkedSDL2VersionInt <= SDL_VERSIONNUM(2, 0, 15))) { + mode.w = 1024; + mode.h = 768; + mode.format = SDL_PIXELFORMAT_RGB888; + } + } + if ((mode.w <= 0) || (mode.h <= 0)) { - continue; + continue; /* bogus mode for whatever reason, ignore it. */ } if (mode.w > 65535 || mode.h > 65535) { @@ -1609,9 +1621,12 @@ Init12VidModes(void) static int Init12Video(void) { + const char *driver = SDL20_GetCurrentVideoDriver(); SDL_DisplayMode mode; int i; + IsDummyVideo = driver && (SDL20_strcmp(driver, "dummy") == 0); + for (i = 0; i < SDL12_MAXEVENTS-1; i++) EventQueuePool[i].next = &EventQueuePool[i+1]; EventQueuePool[SDL12_MAXEVENTS-1].next = NULL; @@ -3445,8 +3460,12 @@ SDL_ListModes(const SDL12_PixelFormat *format12, Uint32 flags) return NULL; } + if (IsDummyVideo) { + return (SDL12_Rect **) -1; /* 1.2's dummy driver always returns -1, and it's useful to special-case that. */ + } + if (!(flags & SDL12_FULLSCREEN)) { - return (SDL12_Rect **) (-1); /* any resolution is fine. */ + return (SDL12_Rect **) -1; /* any resolution is fine. */ } if (format12 && (format12 != VideoInfo12.vfmt)) { From 512fe3bbe78df56d20a4947d623aa590a99bfc4e Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 18 Jun 2021 00:34:55 -0400 Subject: [PATCH 083/606] SDL_AudioCVT may be (or may not be...!) packed differently in SDL2. --- src/SDL12_compat.c | 72 +++++++++++++++++++++++++++++++++++++ src/SDL20_include_wrapper.h | 4 +++ src/SDL20_syms.h | 4 +-- 3 files changed, 78 insertions(+), 2 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 03b019c55..e0b2eac06 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -800,6 +800,23 @@ typedef struct SDL_Joystick *joystick; } JoystickOpenedItem; +/* this is identical to SDL2, except SDL2 forced the structure packing in + some instances, so we can't passthrough without converting the struct. :( */ +typedef struct +{ + int needed; + Uint16 src_format; + Uint16 dst_format; + double rate_incr; + Uint8 *buf; + int len; + int len_cvt; + int len_mult; + double len_ratio; + void (SDLCALL *filters[10])(struct SDL_AudioCVT *cvt, Uint16 format); + int filter_index; +} SDL12_AudioCVT; + #include "SDL_opengl.h" #include "SDL_opengl_glext.h" @@ -6902,6 +6919,61 @@ SDL_CloseAudio(void) } +static SDL_AudioCVT * +AudioCVT12to20(const SDL12_AudioCVT *cvt12, SDL_AudioCVT *cvt20) +{ + SDL_zerop(cvt20); + cvt20->needed = cvt12->needed; + cvt20->src_format = cvt12->src_format; + cvt20->dst_format = cvt12->dst_format; + cvt20->rate_incr = cvt12->rate_incr; + cvt20->buf = cvt12->buf; + cvt20->len = cvt12->len; + cvt20->len_cvt = cvt12->len_cvt; + cvt20->len_mult = cvt12->len_mult; + cvt20->len_ratio = cvt12->len_ratio; + SDL20_memcpy(cvt20->filters, cvt12->filters, sizeof (cvt12->filters)); + cvt20->filter_index = cvt12->filter_index; + return cvt20; +} + +static SDL12_AudioCVT * +AudioCVT20to12(const SDL_AudioCVT *cvt20, SDL12_AudioCVT *cvt12) +{ + SDL_zerop(cvt12); + cvt12->needed = cvt20->needed; + cvt12->src_format = cvt20->src_format; + cvt12->dst_format = cvt20->dst_format; + cvt12->rate_incr = cvt20->rate_incr; + cvt12->buf = cvt20->buf; + cvt12->len = cvt20->len; + cvt12->len_cvt = cvt20->len_cvt; + cvt12->len_mult = cvt20->len_mult; + cvt12->len_ratio = cvt20->len_ratio; + SDL20_memcpy(cvt12->filters, cvt20->filters, sizeof (cvt20->filters)); + cvt12->filter_index = cvt20->filter_index; + return cvt12; +} + +DECLSPEC int SDLCALL +SDL_BuildAudioCVT(SDL12_AudioCVT *cvt12, Uint16 src_format, Uint8 src_channels, int src_rate, Uint16 dst_format, Uint8 dst_channels, int dst_rate) +{ + SDL_AudioCVT cvt20; + const int retval = SDL20_BuildAudioCVT(&cvt20, src_format, src_channels, src_rate, dst_format, dst_channels, dst_rate); + AudioCVT20to12(&cvt20, cvt12); /* SDL 1.2 derefences cvt12 without checking for NULL */ + return retval; +} + +DECLSPEC int SDLCALL +SDL_ConvertAudio(SDL12_AudioCVT *cvt12) +{ + /* neither SDL 1.2 nor 2.0 makes sure cvt12 isn't NULL here. :/ */ + SDL_AudioCVT cvt20; + const int retval = SDL20_ConvertAudio(AudioCVT12to20(cvt12, &cvt20)); + AudioCVT20to12(&cvt20, cvt12); + return retval; +} + /* SDL_GL_DisableContext and SDL_GL_EnableContext_Thread are not real SDL 1.2 APIs, but some idTech4 games shipped with a custom SDL 1.2 build that added diff --git a/src/SDL20_include_wrapper.h b/src/SDL20_include_wrapper.h index f9d6c35e1..5316cda83 100644 --- a/src/SDL20_include_wrapper.h +++ b/src/SDL20_include_wrapper.h @@ -96,6 +96,8 @@ #define SDL_UnlockSurface IGNORE_THIS_VERSION_OF_SDL_UnlockSurface #define SDL_GetKeyName IGNORE_THIS_VERSION_OF_SDL_GetKeyName #define SDL_VideoInit IGNORE_THIS_VERSION_OF_SDL_VideoInit +#define SDL_BuildAudioCVT IGNORE_THIS_VERSION_OF_SDL_BuildAudioCVT +#define SDL_ConvertAudio IGNORE_THIS_VERSION_OF_SDL_ConvertAudio #define BUILD_SDL 1 @@ -201,6 +203,8 @@ typedef void (__cdecl *pfnSDL_CurrentEndThread) (unsigned); #undef SDL_UnlockSurface #undef SDL_GetKeyName #undef SDL_VideoInit +#undef SDL_BuildAudioCVT +#undef SDL_ConvertAudio #ifdef SDL_mutexP #undef SDL_mutexP diff --git a/src/SDL20_syms.h b/src/SDL20_syms.h index 9a8ef5b31..baf6a024d 100644 --- a/src/SDL20_syms.h +++ b/src/SDL20_syms.h @@ -194,8 +194,8 @@ SDL20_SYM(void,CloseAudio,(void),(),) SDL20_SYM(SDL_AudioStatus,GetAudioStatus,(void),(),return) SDL20_SYM(void,PauseAudio,(int a),(a),) SDL20_SYM_PASSTHROUGH(void,FreeWAV,(Uint8 *a),(a),) -SDL20_SYM_PASSTHROUGH(int,BuildAudioCVT,(SDL_AudioCVT *a, Uint16 b, Uint8 c, int d, Uint16 e, Uint8 f, int g),(a,b,c,d,e,f,g),return) -SDL20_SYM_PASSTHROUGH(int,ConvertAudio,(SDL_AudioCVT *a),(a),return) +SDL20_SYM(int,BuildAudioCVT,(SDL_AudioCVT *a, Uint16 b, Uint8 c, int d, Uint16 e, Uint8 f, int g),(a,b,c,d,e,f,g),return) +SDL20_SYM(int,ConvertAudio,(SDL_AudioCVT *a),(a),return) SDL20_SYM_PASSTHROUGH(void,MixAudio,(Uint8 *a, const Uint8 *b, Uint32 c, int d),(a,b,c,d),) SDL20_SYM_PASSTHROUGH(void,LockAudio,(void),(),) SDL20_SYM_PASSTHROUGH(void,UnlockAudio,(void),(),) From da3b11a81bf9cd9628f31739e359ff7849fd43d9 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 18 Jun 2021 00:36:33 -0400 Subject: [PATCH 084/606] Fix a struct typedef to match the others. --- src/SDL12_compat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index e0b2eac06..a61101a05 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -776,7 +776,7 @@ typedef struct Uint32 offset; } SDL12_CDtrack; -typedef struct SDL12_CD +typedef struct { int id; SDL12_CDstatus status; From c57540ce2a0d0906eadd3a4d23697f6bc3f2504e Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 18 Jun 2021 00:36:52 -0400 Subject: [PATCH 085/606] Fix a function signature to match the others. --- src/SDL12_compat.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index a61101a05..ff2d04552 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1740,7 +1740,7 @@ SDL_Init(Uint32 sdl12flags) static void -InitFlags12To20(const Uint32 flags12, Uint32 *_flags20, Uint32 *_extraflags) +InitFlags12to20(const Uint32 flags12, Uint32 *_flags20, Uint32 *_extraflags) { Uint32 flags20 = 0; Uint32 extraflags = 0; @@ -1782,7 +1782,7 @@ DECLSPEC Uint32 SDLCALL SDL_WasInit(Uint32 sdl12flags) { Uint32 sdl20flags, extraflags; - InitFlags12To20(sdl12flags, &sdl20flags, &extraflags); + InitFlags12to20(sdl12flags, &sdl20flags, &extraflags); return InitFlags20to12(SDL20_WasInit(sdl20flags)) | extraflags; } @@ -1819,7 +1819,7 @@ DECLSPEC void SDLCALL SDL_QuitSubSystem(Uint32 sdl12flags) { Uint32 sdl20flags, extraflags; - InitFlags12To20(sdl12flags, &sdl20flags, &extraflags); + InitFlags12to20(sdl12flags, &sdl20flags, &extraflags); if (extraflags & SDL12_INIT_CDROM) { QuitCDSubsystem(); From 0232ad4e6d7bc27c1d3d0fa3bbd9b1dd9f883fa5 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Fri, 18 Jun 2021 14:30:50 +0300 Subject: [PATCH 086/606] minor build fix. --- src/SDL12_compat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index ff2d04552..54ab6c74b 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1642,7 +1642,7 @@ Init12Video(void) SDL_DisplayMode mode; int i; - IsDummyVideo = driver && (SDL20_strcmp(driver, "dummy") == 0); + IsDummyVideo = ((driver != NULL) && (SDL20_strcmp(driver, "dummy") == 0)) ? SDL_TRUE : SDL_FALSE; for (i = 0; i < SDL12_MAXEVENTS-1; i++) EventQueuePool[i].next = &EventQueuePool[i+1]; From f44f295a0a7ede567dee9610127d069ccf281720 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 18 Jun 2021 10:18:24 -0400 Subject: [PATCH 087/606] Try to deal with surface creations with wonky color masks. This happens to fix Bug #46 by virtue of how this is implemented, and also causes an intentional bug in an SDL_perl unit test to pass as expected... it corrects _bug_ compatibility for specific known issues. It's likely not a perfect solution, but it's only intended to work around apps with bugs that SDL 1.2 tolerated. --- src/SDL12_compat.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 54ab6c74b..7c7fc09ab 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -3290,6 +3290,21 @@ SDL_CreateRGBSurface(Uint32 flags12, int width, int height, int depth, Uint32 Rm surface20 = SDL20_CreateRGBSurface(0, width, height, depth, Rmask, Gmask, Bmask, Amask); } + /* SDL 1.2 would make a surface from almost any masks, even if it doesn't + make sense; specifically, it will make a surface if a color mask is + bogus. Sometimes this even worked because it would eventually land in + a generic blitter that just copied data blindly. SDL2 wants more strict + pixel formats, so try to detect this case and try again with a standard + format. */ + if ((surface20 == NULL) && (depth >= 24) && (SDL20_MasksToPixelFormatEnum(depth, Rmask, Gmask, Bmask, Amask) == SDL_PIXELFORMAT_UNKNOWN)) { + /* I have no illusions this is correct, it just works for the known problem cases so far. */ + Rmask = SDL_SwapLE32(0x000000FF); + Gmask = SDL_SwapLE32(0x0000FF00); + Bmask = SDL_SwapLE32(0x00FF0000); + Amask = SDL_SwapLE32(Amask ? 0xFF000000 : 0x00000000); + surface20 = SDL20_CreateRGBSurface(0, width, height, depth, Rmask, Gmask, Bmask, Amask); + } + surface12 = Surface20to12(surface20); if (!surface12) { SDL20_FreeSurface(surface20); From 0da355b56d41477b653d3d76d75b7918c89afdf1 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Fri, 18 Jun 2021 20:41:32 +0300 Subject: [PATCH 088/606] SDL_opengl.h: upgrade glext part to version 39 with Khronos license Specifically this glext.h: https://github.com/mesa3d/mesa/blob/7048545c44ccc5a2ffe716705c128d7a37dff766/include/GL/glext.h This gets rid of the non-free 'SGI Free B v1.1' license. Fixes: https://github.com/libsdl-org/sdl12-compat/issues/105 --- include/SDL/SDL_opengl.h | 835 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 799 insertions(+), 36 deletions(-) diff --git a/include/SDL/SDL_opengl.h b/include/SDL/SDL_opengl.h index 8879daeed..000c87336 100644 --- a/include/SDL/SDL_opengl.h +++ b/include/SDL/SDL_opengl.h @@ -23,11 +23,8 @@ functionality to let you build an SDL-1.2-based project without having the real SDL-1.2 available to you. */ -/* This file is a verbatim copy of SDL 1.2's, as most of it is covered by -SGI Free Software License B, Version 1.1 and not LGPL, and the rest was -written by Sam Lantinga. The only exceptions are patches for doxygen comments -and a MacOS Classic #include fix; both were from external contributors and -both were removed here. */ +/* This file is a verbatim copy of SDL 1.2's, the only exceptions being +doxygen comments and MacOS Classic #include fixes - both removed here. */ #include "SDL_config.h" @@ -56,8 +53,7 @@ both were removed here. */ #undef __gl_glext_h_ #endif -/* This file taken from "GLext.h" from the Jeff Molofee OpenGL tutorials. - * It is included here because glext.h is not available on some systems. +/* This is included here because glext.h is not available on some systems. * If you don't want this version included, simply define "NO_SDL_GLEXT" */ #ifndef NO_SDL_GLEXT @@ -70,32 +66,26 @@ extern "C" { #endif /* -** License Applicability. Except to the extent portions of this file are -** made subject to an alternative license as permitted in the SGI Free -** Software License B, Version 1.1 (the "License"), the contents of this -** file are subject only to the provisions of the License. You may not use -** this file except in compliance with the License. You may obtain a copy -** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 -** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** Copyright (c) 2007 The Khronos Group Inc. ** -** http://oss.sgi.com/projects/FreeB +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are furnished to do so, subject to +** the following conditions: ** -** Note that, as provided in the License, the Software is distributed on an -** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS -** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND -** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A -** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** The above copyright notice and this permission notice shall be included +** in all copies or substantial portions of the Materials. ** -** Original Code. The Original Code is: OpenGL Sample Implementation, -** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, -** Inc. The Original Code is Copyright (c) 1991-2004 Silicon Graphics, Inc. -** Copyright in any portions created by third parties is as indicated -** elsewhere herein. All Rights Reserved. -** -** Additional Notice Provisions: This software was created using the -** OpenGL(R) version 1.2.1 Sample Implementation published by SGI, but has -** not been independently verified as being compliant with the OpenGL(R) -** version 1.2.1 Specification. +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. */ #if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) @@ -116,9 +106,9 @@ extern "C" { /*************************************************************/ /* Header file version number, required by OpenGL ABI for Linux */ -/* glext.h last updated 2005/06/20 */ -/* Current version at http://oss.sgi.com/projects/ogl-sample/registry/ */ -#define GL_GLEXT_VERSION 29 +/* glext.h last updated 2007/02/12 */ +/* Current version at http://www.opengl.org/registry/ */ +#define GL_GLEXT_VERSION 39 #ifndef GL_VERSION_1_2 #define GL_UNSIGNED_BYTE_3_3_2 0x8032 @@ -523,6 +513,32 @@ extern "C" { #define GL_STENCIL_BACK_WRITEMASK 0x8CA5 #endif +#ifndef GL_VERSION_2_1 +#define GL_CURRENT_RASTER_SECONDARY_COLOR 0x845F +#define GL_PIXEL_PACK_BUFFER 0x88EB +#define GL_PIXEL_UNPACK_BUFFER 0x88EC +#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED +#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF +#define GL_FLOAT_MAT2x3 0x8B65 +#define GL_FLOAT_MAT2x4 0x8B66 +#define GL_FLOAT_MAT3x2 0x8B67 +#define GL_FLOAT_MAT3x4 0x8B68 +#define GL_FLOAT_MAT4x2 0x8B69 +#define GL_FLOAT_MAT4x3 0x8B6A +#define GL_SRGB 0x8C40 +#define GL_SRGB8 0x8C41 +#define GL_SRGB_ALPHA 0x8C42 +#define GL_SRGB8_ALPHA8 0x8C43 +#define GL_SLUMINANCE_ALPHA 0x8C44 +#define GL_SLUMINANCE8_ALPHA8 0x8C45 +#define GL_SLUMINANCE 0x8C46 +#define GL_SLUMINANCE8 0x8C47 +#define GL_COMPRESSED_SRGB 0x8C48 +#define GL_COMPRESSED_SRGB_ALPHA 0x8C49 +#define GL_COMPRESSED_SLUMINANCE 0x8C4A +#define GL_COMPRESSED_SLUMINANCE_ALPHA 0x8C4B +#endif + #ifndef GL_ARB_multitexture #define GL_TEXTURE0_ARB 0x84C0 #define GL_TEXTURE1_ARB 0x84C1 @@ -3057,7 +3073,6 @@ extern "C" { #define GL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5 #define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT 0x8CD6 #define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT 0x8CD7 -#define GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT 0x8CD8 #define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT 0x8CD9 #define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT 0x8CDA #define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT 0x8CDB @@ -3102,6 +3117,328 @@ extern "C" { #ifndef GL_GREMEDY_string_marker #endif +#ifndef GL_EXT_packed_depth_stencil +#define GL_DEPTH_STENCIL_EXT 0x84F9 +#define GL_UNSIGNED_INT_24_8_EXT 0x84FA +#define GL_DEPTH24_STENCIL8_EXT 0x88F0 +#define GL_TEXTURE_STENCIL_SIZE_EXT 0x88F1 +#endif + +#ifndef GL_EXT_stencil_clear_tag +#define GL_STENCIL_TAG_BITS_EXT 0x88F2 +#define GL_STENCIL_CLEAR_TAG_VALUE_EXT 0x88F3 +#endif + +#ifndef GL_EXT_texture_sRGB +#define GL_SRGB_EXT 0x8C40 +#define GL_SRGB8_EXT 0x8C41 +#define GL_SRGB_ALPHA_EXT 0x8C42 +#define GL_SRGB8_ALPHA8_EXT 0x8C43 +#define GL_SLUMINANCE_ALPHA_EXT 0x8C44 +#define GL_SLUMINANCE8_ALPHA8_EXT 0x8C45 +#define GL_SLUMINANCE_EXT 0x8C46 +#define GL_SLUMINANCE8_EXT 0x8C47 +#define GL_COMPRESSED_SRGB_EXT 0x8C48 +#define GL_COMPRESSED_SRGB_ALPHA_EXT 0x8C49 +#define GL_COMPRESSED_SLUMINANCE_EXT 0x8C4A +#define GL_COMPRESSED_SLUMINANCE_ALPHA_EXT 0x8C4B +#define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT 0x8C4C +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F +#endif + +#ifndef GL_EXT_framebuffer_blit +#define GL_READ_FRAMEBUFFER_EXT 0x8CA8 +#define GL_DRAW_FRAMEBUFFER_EXT 0x8CA9 +#define GL_READ_FRAMEBUFFER_BINDING_EXT 0x8CAA +#define GL_DRAW_FRAMEBUFFER_BINDING_EXT GL_FRAMEBUFFER_BINDING_EXT +#endif + +#ifndef GL_EXT_framebuffer_multisample +#define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56 +#define GL_MAX_SAMPLES_EXT 0x8D57 +#endif + +#ifndef GL_MESAX_texture_stack +#define GL_TEXTURE_1D_STACK_MESAX 0x8759 +#define GL_TEXTURE_2D_STACK_MESAX 0x875A +#define GL_PROXY_TEXTURE_1D_STACK_MESAX 0x875B +#define GL_PROXY_TEXTURE_2D_STACK_MESAX 0x875C +#define GL_TEXTURE_1D_STACK_BINDING_MESAX 0x875D +#define GL_TEXTURE_2D_STACK_BINDING_MESAX 0x875E +#endif + +#ifndef GL_EXT_timer_query +#define GL_TIME_ELAPSED_EXT 0x88BF +#endif + +#ifndef GL_EXT_gpu_program_parameters +#endif + +#ifndef GL_APPLE_flush_buffer_range +#define GL_BUFFER_SERIALIZED_MODIFY_APPLE 0x8A12 +#define GL_BUFFER_FLUSHING_UNMAP_APPLE 0x8A13 +#endif + +#ifndef GL_NV_gpu_program4 +#define GL_MIN_PROGRAM_TEXEL_OFFSET_NV 0x8904 +#define GL_MAX_PROGRAM_TEXEL_OFFSET_NV 0x8905 +#define GL_PROGRAM_ATTRIB_COMPONENTS_NV 0x8906 +#define GL_PROGRAM_RESULT_COMPONENTS_NV 0x8907 +#define GL_MAX_PROGRAM_ATTRIB_COMPONENTS_NV 0x8908 +#define GL_MAX_PROGRAM_RESULT_COMPONENTS_NV 0x8909 +#define GL_MAX_PROGRAM_GENERIC_ATTRIBS_NV 0x8DA5 +#define GL_MAX_PROGRAM_GENERIC_RESULTS_NV 0x8DA6 +#endif + +#ifndef GL_NV_geometry_program4 +#define GL_LINES_ADJACENCY_EXT 0x000A +#define GL_LINE_STRIP_ADJACENCY_EXT 0x000B +#define GL_TRIANGLES_ADJACENCY_EXT 0x000C +#define GL_TRIANGLE_STRIP_ADJACENCY_EXT 0x000D +#define GL_GEOMETRY_PROGRAM_NV 0x8C26 +#define GL_MAX_PROGRAM_OUTPUT_VERTICES_NV 0x8C27 +#define GL_MAX_PROGRAM_TOTAL_OUTPUT_COMPONENTS_NV 0x8C28 +#define GL_GEOMETRY_VERTICES_OUT_EXT 0x8DDA +#define GL_GEOMETRY_INPUT_TYPE_EXT 0x8DDB +#define GL_GEOMETRY_OUTPUT_TYPE_EXT 0x8DDC +#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT 0x8C29 +#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT 0x8DA7 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT 0x8DA8 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT 0x8DA9 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT 0x8CD4 +#define GL_PROGRAM_POINT_SIZE_EXT 0x8642 +#endif + +#ifndef GL_EXT_geometry_shader4 +#define GL_GEOMETRY_SHADER_EXT 0x8DD9 +/* reuse GL_GEOMETRY_VERTICES_OUT_EXT */ +/* reuse GL_GEOMETRY_INPUT_TYPE_EXT */ +/* reuse GL_GEOMETRY_OUTPUT_TYPE_EXT */ +/* reuse GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT */ +#define GL_MAX_GEOMETRY_VARYING_COMPONENTS_EXT 0x8DDD +#define GL_MAX_VERTEX_VARYING_COMPONENTS_EXT 0x8DDE +#define GL_MAX_VARYING_COMPONENTS_EXT 0x8B4B +#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT 0x8DDF +#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT 0x8DE0 +#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT 0x8DE1 +/* reuse GL_LINES_ADJACENCY_EXT */ +/* reuse GL_LINE_STRIP_ADJACENCY_EXT */ +/* reuse GL_TRIANGLES_ADJACENCY_EXT */ +/* reuse GL_TRIANGLE_STRIP_ADJACENCY_EXT */ +/* reuse GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT */ +/* reuse GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT */ +/* reuse GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT */ +/* reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT */ +/* reuse GL_PROGRAM_POINT_SIZE_EXT */ +#endif + +#ifndef GL_NV_vertex_program4 +#define GL_VERTEX_ATTRIB_ARRAY_INTEGER_NV 0x88FD +#endif + +#ifndef GL_EXT_gpu_shader4 +#define GL_SAMPLER_1D_ARRAY_EXT 0x8DC0 +#define GL_SAMPLER_2D_ARRAY_EXT 0x8DC1 +#define GL_SAMPLER_BUFFER_EXT 0x8DC2 +#define GL_SAMPLER_1D_ARRAY_SHADOW_EXT 0x8DC3 +#define GL_SAMPLER_2D_ARRAY_SHADOW_EXT 0x8DC4 +#define GL_SAMPLER_CUBE_SHADOW_EXT 0x8DC5 +#define GL_UNSIGNED_INT_VEC2_EXT 0x8DC6 +#define GL_UNSIGNED_INT_VEC3_EXT 0x8DC7 +#define GL_UNSIGNED_INT_VEC4_EXT 0x8DC8 +#define GL_INT_SAMPLER_1D_EXT 0x8DC9 +#define GL_INT_SAMPLER_2D_EXT 0x8DCA +#define GL_INT_SAMPLER_3D_EXT 0x8DCB +#define GL_INT_SAMPLER_CUBE_EXT 0x8DCC +#define GL_INT_SAMPLER_2D_RECT_EXT 0x8DCD +#define GL_INT_SAMPLER_1D_ARRAY_EXT 0x8DCE +#define GL_INT_SAMPLER_2D_ARRAY_EXT 0x8DCF +#define GL_INT_SAMPLER_BUFFER_EXT 0x8DD0 +#define GL_UNSIGNED_INT_SAMPLER_1D_EXT 0x8DD1 +#define GL_UNSIGNED_INT_SAMPLER_2D_EXT 0x8DD2 +#define GL_UNSIGNED_INT_SAMPLER_3D_EXT 0x8DD3 +#define GL_UNSIGNED_INT_SAMPLER_CUBE_EXT 0x8DD4 +#define GL_UNSIGNED_INT_SAMPLER_2D_RECT_EXT 0x8DD5 +#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY_EXT 0x8DD6 +#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY_EXT 0x8DD7 +#define GL_UNSIGNED_INT_SAMPLER_BUFFER_EXT 0x8DD8 +#endif + +#ifndef GL_EXT_draw_instanced +#endif + +#ifndef GL_EXT_packed_float +#define GL_R11F_G11F_B10F_EXT 0x8C3A +#define GL_UNSIGNED_INT_10F_11F_11F_REV_EXT 0x8C3B +#define GL_RGBA_SIGNED_COMPONENTS_EXT 0x8C3C +#endif + +#ifndef GL_EXT_texture_array +#define GL_TEXTURE_1D_ARRAY_EXT 0x8C18 +#define GL_PROXY_TEXTURE_1D_ARRAY_EXT 0x8C19 +#define GL_TEXTURE_2D_ARRAY_EXT 0x8C1A +#define GL_PROXY_TEXTURE_2D_ARRAY_EXT 0x8C1B +#define GL_TEXTURE_BINDING_1D_ARRAY_EXT 0x8C1C +#define GL_TEXTURE_BINDING_2D_ARRAY_EXT 0x8C1D +#define GL_MAX_ARRAY_TEXTURE_LAYERS_EXT 0x88FF +#define GL_COMPARE_REF_DEPTH_TO_TEXTURE_EXT 0x884E +/* reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT */ +#endif + +#ifndef GL_EXT_texture_buffer_object +#define GL_TEXTURE_BUFFER_EXT 0x8C2A +#define GL_MAX_TEXTURE_BUFFER_SIZE_EXT 0x8C2B +#define GL_TEXTURE_BINDING_BUFFER_EXT 0x8C2C +#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_EXT 0x8C2D +#define GL_TEXTURE_BUFFER_FORMAT_EXT 0x8C2E +#endif + +#ifndef GL_EXT_texture_compression_latc +#define GL_COMPRESSED_LUMINANCE_LATC1_EXT 0x8C70 +#define GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT 0x8C71 +#define GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT 0x8C72 +#define GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT 0x8C73 +#endif + +#ifndef GL_EXT_texture_compression_rgtc +#define GL_COMPRESSED_RED_RGTC1_EXT 0x8DBB +#define GL_COMPRESSED_SIGNED_RED_RGTC1_EXT 0x8DBC +#define GL_COMPRESSED_RED_GREEN_RGTC2_EXT 0x8DBD +#define GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT 0x8DBE +#endif + +#ifndef GL_EXT_texture_shared_exponent +#define GL_RGB9_E5_EXT 0x8C3D +#define GL_UNSIGNED_INT_5_9_9_9_REV_EXT 0x8C3E +#define GL_TEXTURE_SHARED_SIZE_EXT 0x8C3F +#endif + +#ifndef GL_NV_depth_buffer_float +#define GL_DEPTH_COMPONENT32F_NV 0x8DAB +#define GL_DEPTH32F_STENCIL8_NV 0x8DAC +#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV_NV 0x8DAD +#define GL_DEPTH_BUFFER_FLOAT_MODE_NV 0x8DAF +#endif + +#ifndef GL_NV_fragment_program4 +#endif + +#ifndef GL_NV_framebuffer_multisample_coverage +#define GL_RENDERBUFFER_COVERAGE_SAMPLES_NV 0x8CAB +#define GL_RENDERBUFFER_COLOR_SAMPLES_NV 0x8E10 +#define GL_MAX_MULTISAMPLE_COVERAGE_MODES_NV 0x8E11 +#define GL_MULTISAMPLE_COVERAGE_MODES_NV 0x8E12 +#endif + +#ifndef GL_EXT_framebuffer_sRGB +#define GL_FRAMEBUFFER_SRGB_EXT 0x8DB9 +#define GL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x8DBA +#endif + +#ifndef GL_NV_geometry_shader4 +#endif + +#ifndef GL_NV_parameter_buffer_object +#define GL_MAX_PROGRAM_PARAMETER_BUFFER_BINDINGS_NV 0x8DA0 +#define GL_MAX_PROGRAM_PARAMETER_BUFFER_SIZE_NV 0x8DA1 +#define GL_VERTEX_PROGRAM_PARAMETER_BUFFER_NV 0x8DA2 +#define GL_GEOMETRY_PROGRAM_PARAMETER_BUFFER_NV 0x8DA3 +#define GL_FRAGMENT_PROGRAM_PARAMETER_BUFFER_NV 0x8DA4 +#endif + +#ifndef GL_EXT_draw_buffers2 +#endif + +#ifndef GL_NV_transform_feedback +#define GL_BACK_PRIMARY_COLOR_NV 0x8C77 +#define GL_BACK_SECONDARY_COLOR_NV 0x8C78 +#define GL_TEXTURE_COORD_NV 0x8C79 +#define GL_CLIP_DISTANCE_NV 0x8C7A +#define GL_VERTEX_ID_NV 0x8C7B +#define GL_PRIMITIVE_ID_NV 0x8C7C +#define GL_GENERIC_ATTRIB_NV 0x8C7D +#define GL_TRANSFORM_FEEDBACK_ATTRIBS_NV 0x8C7E +#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_NV 0x8C7F +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_NV 0x8C80 +#define GL_ACTIVE_VARYINGS_NV 0x8C81 +#define GL_ACTIVE_VARYING_MAX_LENGTH_NV 0x8C82 +#define GL_TRANSFORM_FEEDBACK_VARYINGS_NV 0x8C83 +#define GL_TRANSFORM_FEEDBACK_BUFFER_START_NV 0x8C84 +#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_NV 0x8C85 +#define GL_TRANSFORM_FEEDBACK_RECORD_NV 0x8C86 +#define GL_PRIMITIVES_GENERATED_NV 0x8C87 +#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_NV 0x8C88 +#define GL_RASTERIZER_DISCARD_NV 0x8C89 +#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_ATTRIBS_NV 0x8C8A +#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_NV 0x8C8B +#define GL_INTERLEAVED_ATTRIBS_NV 0x8C8C +#define GL_SEPARATE_ATTRIBS_NV 0x8C8D +#define GL_TRANSFORM_FEEDBACK_BUFFER_NV 0x8C8E +#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_NV 0x8C8F +#endif + +#ifndef GL_EXT_bindable_uniform +#define GL_MAX_VERTEX_BINDABLE_UNIFORMS_EXT 0x8DE2 +#define GL_MAX_FRAGMENT_BINDABLE_UNIFORMS_EXT 0x8DE3 +#define GL_MAX_GEOMETRY_BINDABLE_UNIFORMS_EXT 0x8DE4 +#define GL_MAX_BINDABLE_UNIFORM_SIZE_EXT 0x8DED +#define GL_UNIFORM_BUFFER_EXT 0x8DEE +#define GL_UNIFORM_BUFFER_BINDING_EXT 0x8DEF +#endif + +#ifndef GL_EXT_texture_integer +#define GL_RGBA32UI_EXT 0x8D70 +#define GL_RGB32UI_EXT 0x8D71 +#define GL_ALPHA32UI_EXT 0x8D72 +#define GL_INTENSITY32UI_EXT 0x8D73 +#define GL_LUMINANCE32UI_EXT 0x8D74 +#define GL_LUMINANCE_ALPHA32UI_EXT 0x8D75 +#define GL_RGBA16UI_EXT 0x8D76 +#define GL_RGB16UI_EXT 0x8D77 +#define GL_ALPHA16UI_EXT 0x8D78 +#define GL_INTENSITY16UI_EXT 0x8D79 +#define GL_LUMINANCE16UI_EXT 0x8D7A +#define GL_LUMINANCE_ALPHA16UI_EXT 0x8D7B +#define GL_RGBA8UI_EXT 0x8D7C +#define GL_RGB8UI_EXT 0x8D7D +#define GL_ALPHA8UI_EXT 0x8D7E +#define GL_INTENSITY8UI_EXT 0x8D7F +#define GL_LUMINANCE8UI_EXT 0x8D80 +#define GL_LUMINANCE_ALPHA8UI_EXT 0x8D81 +#define GL_RGBA32I_EXT 0x8D82 +#define GL_RGB32I_EXT 0x8D83 +#define GL_ALPHA32I_EXT 0x8D84 +#define GL_INTENSITY32I_EXT 0x8D85 +#define GL_LUMINANCE32I_EXT 0x8D86 +#define GL_LUMINANCE_ALPHA32I_EXT 0x8D87 +#define GL_RGBA16I_EXT 0x8D88 +#define GL_RGB16I_EXT 0x8D89 +#define GL_ALPHA16I_EXT 0x8D8A +#define GL_INTENSITY16I_EXT 0x8D8B +#define GL_LUMINANCE16I_EXT 0x8D8C +#define GL_LUMINANCE_ALPHA16I_EXT 0x8D8D +#define GL_RGBA8I_EXT 0x8D8E +#define GL_RGB8I_EXT 0x8D8F +#define GL_ALPHA8I_EXT 0x8D90 +#define GL_INTENSITY8I_EXT 0x8D91 +#define GL_LUMINANCE8I_EXT 0x8D92 +#define GL_LUMINANCE_ALPHA8I_EXT 0x8D93 +#define GL_RED_INTEGER_EXT 0x8D94 +#define GL_GREEN_INTEGER_EXT 0x8D95 +#define GL_BLUE_INTEGER_EXT 0x8D96 +#define GL_ALPHA_INTEGER_EXT 0x8D97 +#define GL_RGB_INTEGER_EXT 0x8D98 +#define GL_RGBA_INTEGER_EXT 0x8D99 +#define GL_BGR_INTEGER_EXT 0x8D9A +#define GL_BGRA_INTEGER_EXT 0x8D9B +#define GL_LUMINANCE_INTEGER_EXT 0x8D9C +#define GL_LUMINANCE_ALPHA_INTEGER_EXT 0x8D9D +#define GL_RGBA_INTEGER_MODE_EXT 0x8D9E +#endif + /*************************************************************/ @@ -3152,6 +3489,50 @@ typedef unsigned short GLhalfARB; typedef unsigned short GLhalfNV; #endif +#ifndef GLEXT_64_TYPES_DEFINED +/* This code block is duplicated in glext.h, so must be protected */ +#define GLEXT_64_TYPES_DEFINED +/* Define int32_t, int64_t, and uint64_t types for UST/MSC */ +/* (as used in the GL_EXT_timer_query extension). */ +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +#include +#elif defined(__sun__) +#include +#if defined(__STDC__) +#if defined(__arch64__) +typedef long int int64_t; +typedef unsigned long int uint64_t; +#else +typedef long long int int64_t; +typedef unsigned long long int uint64_t; +#endif /* __arch64__ */ +#endif /* __STDC__ */ +#elif defined( __VMS ) +#include +#elif defined(__SCO__) || defined(__USLC__) +#include +#elif defined(__UNIXOS2__) || defined(__SOL64__) +typedef long int int32_t; +typedef long long int int64_t; +typedef unsigned long long int uint64_t; +#elif defined(_WIN32) && (defined(__GNUC__)||defined(__WATCOMC__)) +#include +#elif defined(_WIN32) +#if 0 /* handled by SDL_config_windows.h */ +typedef __int32 int32_t; +typedef __int64 int64_t; +typedef unsigned __int64 uint64_t; +#endif /* */ +#else +#include /* Fallback option */ +#endif +#endif + +#ifndef GL_EXT_timer_query +typedef int64_t GLint64EXT; +typedef uint64_t GLuint64EXT; +#endif + #ifndef GL_VERSION_1_2 #define GL_VERSION_1_2 1 #ifdef GL_GLEXT_PROTOTYPES @@ -3664,6 +4045,24 @@ typedef void (APIENTRYP PFNGLVERTEXATTRIB4USVPROC) (GLuint index, const GLushort typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer); #endif +#ifndef GL_VERSION_2_1 +#define GL_VERSION_2_1 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glUniformMatrix2x3fv (GLint, GLsizei, GLboolean, const GLfloat *); +GLAPI void APIENTRY glUniformMatrix3x2fv (GLint, GLsizei, GLboolean, const GLfloat *); +GLAPI void APIENTRY glUniformMatrix2x4fv (GLint, GLsizei, GLboolean, const GLfloat *); +GLAPI void APIENTRY glUniformMatrix4x2fv (GLint, GLsizei, GLboolean, const GLfloat *); +GLAPI void APIENTRY glUniformMatrix3x4fv (GLint, GLsizei, GLboolean, const GLfloat *); +GLAPI void APIENTRY glUniformMatrix4x3fv (GLint, GLsizei, GLboolean, const GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +#endif + #ifndef GL_ARB_multitexture #define GL_ARB_multitexture 1 #ifdef GL_GLEXT_PROTOTYPES @@ -4371,8 +4770,8 @@ typedef void (APIENTRYP PFNGLGETSEPARABLEFILTEREXTPROC) (GLenum target, GLenum f typedef void (APIENTRYP PFNGLSEPARABLEFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column); #endif -#ifndef GL_EXT_color_matrix -#define GL_EXT_color_matrix 1 +#ifndef GL_SGI_color_matrix +#define GL_SGI_color_matrix 1 #endif #ifndef GL_SGI_color_table @@ -6565,6 +6964,370 @@ GLAPI void APIENTRY glStringMarkerGREMEDY (GLsizei, const GLvoid *); typedef void (APIENTRYP PFNGLSTRINGMARKERGREMEDYPROC) (GLsizei len, const GLvoid *string); #endif +#ifndef GL_EXT_packed_depth_stencil +#define GL_EXT_packed_depth_stencil 1 +#endif + +#ifndef GL_EXT_stencil_clear_tag +#define GL_EXT_stencil_clear_tag 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glStencilClearTagEXT (GLsizei, GLuint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLSTENCILCLEARTAGEXTPROC) (GLsizei stencilTagBits, GLuint stencilClearTag); +#endif + +#ifndef GL_EXT_texture_sRGB +#define GL_EXT_texture_sRGB 1 +#endif + +#ifndef GL_EXT_framebuffer_blit +#define GL_EXT_framebuffer_blit 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBlitFramebufferEXT (GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLbitfield, GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLBLITFRAMEBUFFEREXTPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +#endif + +#ifndef GL_EXT_framebuffer_multisample +#define GL_EXT_framebuffer_multisample 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glRenderbufferStorageMultisampleEXT (GLenum, GLsizei, GLenum, GLsizei, GLsizei); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +#endif + +#ifndef GL_MESAX_texture_stack +#define GL_MESAX_texture_stack 1 +#endif + +#ifndef GL_EXT_timer_query +#define GL_EXT_timer_query 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGetQueryObjecti64vEXT (GLuint, GLenum, GLint64EXT *); +GLAPI void APIENTRY glGetQueryObjectui64vEXT (GLuint, GLenum, GLuint64EXT *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLGETQUERYOBJECTI64VEXTPROC) (GLuint id, GLenum pname, GLint64EXT *params); +typedef void (APIENTRYP PFNGLGETQUERYOBJECTUI64VEXTPROC) (GLuint id, GLenum pname, GLuint64EXT *params); +#endif + +#ifndef GL_EXT_gpu_program_parameters +#define GL_EXT_gpu_program_parameters 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glProgramEnvParameters4fvEXT (GLenum, GLuint, GLsizei, const GLfloat *); +GLAPI void APIENTRY glProgramLocalParameters4fvEXT (GLenum, GLuint, GLsizei, const GLfloat *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERS4FVEXTPROC) (GLenum target, GLuint index, GLsizei count, const GLfloat *params); +typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC) (GLenum target, GLuint index, GLsizei count, const GLfloat *params); +#endif + +#ifndef GL_APPLE_flush_buffer_range +#define GL_APPLE_flush_buffer_range 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBufferParameteriAPPLE (GLenum, GLenum, GLint); +GLAPI void APIENTRY glFlushMappedBufferRangeAPPLE (GLenum, GLintptr, GLsizeiptr); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLBUFFERPARAMETERIAPPLEPROC) (GLenum target, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC) (GLenum target, GLintptr offset, GLsizeiptr size); +#endif + +#ifndef GL_NV_gpu_program4 +#define GL_NV_gpu_program4 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glProgramLocalParameterI4iNV (GLenum, GLuint, GLint, GLint, GLint, GLint); +GLAPI void APIENTRY glProgramLocalParameterI4ivNV (GLenum, GLuint, const GLint *); +GLAPI void APIENTRY glProgramLocalParametersI4ivNV (GLenum, GLuint, GLsizei, const GLint *); +GLAPI void APIENTRY glProgramLocalParameterI4uiNV (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint); +GLAPI void APIENTRY glProgramLocalParameterI4uivNV (GLenum, GLuint, const GLuint *); +GLAPI void APIENTRY glProgramLocalParametersI4uivNV (GLenum, GLuint, GLsizei, const GLuint *); +GLAPI void APIENTRY glProgramEnvParameterI4iNV (GLenum, GLuint, GLint, GLint, GLint, GLint); +GLAPI void APIENTRY glProgramEnvParameterI4ivNV (GLenum, GLuint, const GLint *); +GLAPI void APIENTRY glProgramEnvParametersI4ivNV (GLenum, GLuint, GLsizei, const GLint *); +GLAPI void APIENTRY glProgramEnvParameterI4uiNV (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint); +GLAPI void APIENTRY glProgramEnvParameterI4uivNV (GLenum, GLuint, const GLuint *); +GLAPI void APIENTRY glProgramEnvParametersI4uivNV (GLenum, GLuint, GLsizei, const GLuint *); +GLAPI void APIENTRY glGetProgramLocalParameterIivNV (GLenum, GLuint, GLint *); +GLAPI void APIENTRY glGetProgramLocalParameterIuivNV (GLenum, GLuint, GLuint *); +GLAPI void APIENTRY glGetProgramEnvParameterIivNV (GLenum, GLuint, GLint *); +GLAPI void APIENTRY glGetProgramEnvParameterIuivNV (GLenum, GLuint, GLuint *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4INVPROC) (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); +typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4IVNVPROC) (GLenum target, GLuint index, const GLint *params); +typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLint *params); +typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4UINVPROC) (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC) (GLenum target, GLuint index, const GLuint *params); +typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLuint *params); +typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4INVPROC) (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); +typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4IVNVPROC) (GLenum target, GLuint index, const GLint *params); +typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERSI4IVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLint *params); +typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4UINVPROC) (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4UIVNVPROC) (GLenum target, GLuint index, const GLuint *params); +typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERSI4UIVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLuint *params); +typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERIIVNVPROC) (GLenum target, GLuint index, GLint *params); +typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERIUIVNVPROC) (GLenum target, GLuint index, GLuint *params); +typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERIIVNVPROC) (GLenum target, GLuint index, GLint *params); +typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERIUIVNVPROC) (GLenum target, GLuint index, GLuint *params); +#endif + +#ifndef GL_NV_geometry_program4 +#define GL_NV_geometry_program4 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glProgramVertexLimitNV (GLenum, GLint); +GLAPI void APIENTRY glFramebufferTextureEXT (GLenum, GLenum, GLuint, GLint); +GLAPI void APIENTRY glFramebufferTextureLayerEXT (GLenum, GLenum, GLuint, GLint, GLint); +GLAPI void APIENTRY glFramebufferTextureFaceEXT (GLenum, GLenum, GLuint, GLint, GLenum); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLPROGRAMVERTEXLIMITNVPROC) (GLenum target, GLint limit); +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); +#endif + +#ifndef GL_EXT_geometry_shader4 +#define GL_EXT_geometry_shader4 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glProgramParameteriEXT (GLuint, GLenum, GLint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLPROGRAMPARAMETERIEXTPROC) (GLuint program, GLenum pname, GLint value); +#endif + +#ifndef GL_NV_vertex_program4 +#define GL_NV_vertex_program4 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glVertexAttribI1iEXT (GLuint, GLint); +GLAPI void APIENTRY glVertexAttribI2iEXT (GLuint, GLint, GLint); +GLAPI void APIENTRY glVertexAttribI3iEXT (GLuint, GLint, GLint, GLint); +GLAPI void APIENTRY glVertexAttribI4iEXT (GLuint, GLint, GLint, GLint, GLint); +GLAPI void APIENTRY glVertexAttribI1uiEXT (GLuint, GLuint); +GLAPI void APIENTRY glVertexAttribI2uiEXT (GLuint, GLuint, GLuint); +GLAPI void APIENTRY glVertexAttribI3uiEXT (GLuint, GLuint, GLuint, GLuint); +GLAPI void APIENTRY glVertexAttribI4uiEXT (GLuint, GLuint, GLuint, GLuint, GLuint); +GLAPI void APIENTRY glVertexAttribI1ivEXT (GLuint, const GLint *); +GLAPI void APIENTRY glVertexAttribI2ivEXT (GLuint, const GLint *); +GLAPI void APIENTRY glVertexAttribI3ivEXT (GLuint, const GLint *); +GLAPI void APIENTRY glVertexAttribI4ivEXT (GLuint, const GLint *); +GLAPI void APIENTRY glVertexAttribI1uivEXT (GLuint, const GLuint *); +GLAPI void APIENTRY glVertexAttribI2uivEXT (GLuint, const GLuint *); +GLAPI void APIENTRY glVertexAttribI3uivEXT (GLuint, const GLuint *); +GLAPI void APIENTRY glVertexAttribI4uivEXT (GLuint, const GLuint *); +GLAPI void APIENTRY glVertexAttribI4bvEXT (GLuint, const GLbyte *); +GLAPI void APIENTRY glVertexAttribI4svEXT (GLuint, const GLshort *); +GLAPI void APIENTRY glVertexAttribI4ubvEXT (GLuint, const GLubyte *); +GLAPI void APIENTRY glVertexAttribI4usvEXT (GLuint, const GLushort *); +GLAPI void APIENTRY glVertexAttribIPointerEXT (GLuint, GLint, GLenum, GLsizei, const GLvoid *); +GLAPI void APIENTRY glGetVertexAttribIivEXT (GLuint, GLenum, GLint *); +GLAPI void APIENTRY glGetVertexAttribIuivEXT (GLuint, GLenum, GLuint *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IEXTPROC) (GLuint index, GLint x); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IEXTPROC) (GLuint index, GLint x, GLint y); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IEXTPROC) (GLuint index, GLint x, GLint y, GLint z); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IEXTPROC) (GLuint index, GLint x, GLint y, GLint z, GLint w); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIEXTPROC) (GLuint index, GLuint x); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIEXTPROC) (GLuint index, GLuint x, GLuint y); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIEXTPROC) (GLuint index, GLuint x, GLuint y, GLuint z); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIEXTPROC) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IVEXTPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IVEXTPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IVEXTPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IVEXTPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIVEXTPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIVEXTPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIVEXTPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIVEXTPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4BVEXTPROC) (GLuint index, const GLbyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4SVEXTPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UBVEXTPROC) (GLuint index, const GLubyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4USVEXTPROC) (GLuint index, const GLushort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBIPOINTEREXTPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIIVEXTPROC) (GLuint index, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIUIVEXTPROC) (GLuint index, GLenum pname, GLuint *params); +#endif + +#ifndef GL_EXT_gpu_shader4 +#define GL_EXT_gpu_shader4 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGetUniformuivEXT (GLuint, GLint, GLuint *); +GLAPI void APIENTRY glBindFragDataLocationEXT (GLuint, GLuint, const GLchar *); +GLAPI GLint APIENTRY glGetFragDataLocationEXT (GLuint, const GLchar *); +GLAPI void APIENTRY glUniform1uiEXT (GLint, GLuint); +GLAPI void APIENTRY glUniform2uiEXT (GLint, GLuint, GLuint); +GLAPI void APIENTRY glUniform3uiEXT (GLint, GLuint, GLuint, GLuint); +GLAPI void APIENTRY glUniform4uiEXT (GLint, GLuint, GLuint, GLuint, GLuint); +GLAPI void APIENTRY glUniform1uivEXT (GLint, GLsizei, const GLuint *); +GLAPI void APIENTRY glUniform2uivEXT (GLint, GLsizei, const GLuint *); +GLAPI void APIENTRY glUniform3uivEXT (GLint, GLsizei, const GLuint *); +GLAPI void APIENTRY glUniform4uivEXT (GLint, GLsizei, const GLuint *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLGETUNIFORMUIVEXTPROC) (GLuint program, GLint location, GLuint *params); +typedef void (APIENTRYP PFNGLBINDFRAGDATALOCATIONEXTPROC) (GLuint program, GLuint color, const GLchar *name); +typedef GLint (APIENTRYP PFNGLGETFRAGDATALOCATIONEXTPROC) (GLuint program, const GLchar *name); +typedef void (APIENTRYP PFNGLUNIFORM1UIEXTPROC) (GLint location, GLuint v0); +typedef void (APIENTRYP PFNGLUNIFORM2UIEXTPROC) (GLint location, GLuint v0, GLuint v1); +typedef void (APIENTRYP PFNGLUNIFORM3UIEXTPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2); +typedef void (APIENTRYP PFNGLUNIFORM4UIEXTPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +typedef void (APIENTRYP PFNGLUNIFORM1UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLUNIFORM2UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLUNIFORM3UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLUNIFORM4UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); +#endif + +#ifndef GL_EXT_draw_instanced +#define GL_EXT_draw_instanced 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDrawArraysInstancedEXT (GLenum, GLint, GLsizei, GLsizei); +GLAPI void APIENTRY glDrawElementsInstancedEXT (GLenum, GLsizei, GLenum, const GLvoid *, GLsizei); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDEXTPROC) (GLenum mode, GLint start, GLsizei count, GLsizei primcount); +typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDEXTPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount); +#endif + +#ifndef GL_EXT_packed_float +#define GL_EXT_packed_float 1 +#endif + +#ifndef GL_EXT_texture_array +#define GL_EXT_texture_array 1 +#endif + +#ifndef GL_EXT_texture_buffer_object +#define GL_EXT_texture_buffer_object 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTexBufferEXT (GLenum, GLenum, GLuint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLTEXBUFFEREXTPROC) (GLenum target, GLenum internalformat, GLuint buffer); +#endif + +#ifndef GL_EXT_texture_compression_latc +#define GL_EXT_texture_compression_latc 1 +#endif + +#ifndef GL_EXT_texture_compression_rgtc +#define GL_EXT_texture_compression_rgtc 1 +#endif + +#ifndef GL_EXT_texture_shared_exponent +#define GL_EXT_texture_shared_exponent 1 +#endif + +#ifndef GL_NV_depth_buffer_float +#define GL_NV_depth_buffer_float 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDepthRangedNV (GLdouble, GLdouble); +GLAPI void APIENTRY glClearDepthdNV (GLdouble); +GLAPI void APIENTRY glDepthBoundsdNV (GLdouble, GLdouble); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLDEPTHRANGEDNVPROC) (GLdouble zNear, GLdouble zFar); +typedef void (APIENTRYP PFNGLCLEARDEPTHDNVPROC) (GLdouble depth); +typedef void (APIENTRYP PFNGLDEPTHBOUNDSDNVPROC) (GLdouble zmin, GLdouble zmax); +#endif + +#ifndef GL_NV_fragment_program4 +#define GL_NV_fragment_program4 1 +#endif + +#ifndef GL_NV_framebuffer_multisample_coverage +#define GL_NV_framebuffer_multisample_coverage 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glRenderbufferStorageMultisampleCoverageNV (GLenum, GLsizei, GLsizei, GLenum, GLsizei, GLsizei); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC) (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height); +#endif + +#ifndef GL_EXT_framebuffer_sRGB +#define GL_EXT_framebuffer_sRGB 1 +#endif + +#ifndef GL_NV_geometry_shader4 +#define GL_NV_geometry_shader4 1 +#endif + +#ifndef GL_NV_parameter_buffer_object +#define GL_NV_parameter_buffer_object 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glProgramBufferParametersfvNV (GLenum, GLuint, GLuint, GLsizei, const GLfloat *); +GLAPI void APIENTRY glProgramBufferParametersIivNV (GLenum, GLuint, GLuint, GLsizei, const GLint *); +GLAPI void APIENTRY glProgramBufferParametersIuivNV (GLenum, GLuint, GLuint, GLsizei, const GLuint *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLPROGRAMBUFFERPARAMETERSFVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLfloat *params); +typedef void (APIENTRYP PFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLint *params); +typedef void (APIENTRYP PFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLuint *params); +#endif + +#ifndef GL_EXT_draw_buffers2 +#define GL_EXT_draw_buffers2 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glColorMaskIndexedEXT (GLuint, GLboolean, GLboolean, GLboolean, GLboolean); +GLAPI void APIENTRY glGetBooleanIndexedvEXT (GLenum, GLuint, GLboolean *); +GLAPI void APIENTRY glGetIntegerIndexedvEXT (GLenum, GLuint, GLint *); +GLAPI void APIENTRY glEnableIndexedEXT (GLenum, GLuint); +GLAPI void APIENTRY glDisableIndexedEXT (GLenum, GLuint); +GLAPI GLboolean APIENTRY glIsEnabledIndexedEXT (GLenum, GLuint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLCOLORMASKINDEXEDEXTPROC) (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); +typedef void (APIENTRYP PFNGLGETBOOLEANINDEXEDVEXTPROC) (GLenum target, GLuint index, GLboolean *data); +typedef void (APIENTRYP PFNGLGETINTEGERINDEXEDVEXTPROC) (GLenum target, GLuint index, GLint *data); +typedef void (APIENTRYP PFNGLENABLEINDEXEDEXTPROC) (GLenum target, GLuint index); +typedef void (APIENTRYP PFNGLDISABLEINDEXEDEXTPROC) (GLenum target, GLuint index); +typedef GLboolean (APIENTRYP PFNGLISENABLEDINDEXEDEXTPROC) (GLenum target, GLuint index); +#endif + +#ifndef GL_NV_transform_feedback +#define GL_NV_transform_feedback 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBeginTransformFeedbackNV (GLenum); +GLAPI void APIENTRY glEndTransformFeedbackNV (void); +GLAPI void APIENTRY glTransformFeedbackAttribsNV (GLuint, const GLint *, GLenum); +GLAPI void APIENTRY glBindBufferRangeNV (GLenum, GLuint, GLuint, GLintptr, GLsizeiptr); +GLAPI void APIENTRY glBindBufferOffsetNV (GLenum, GLuint, GLuint, GLintptr); +GLAPI void APIENTRY glBindBufferBaseNV (GLenum, GLuint, GLuint); +GLAPI void APIENTRY glTransformFeedbackVaryingsNV (GLuint, GLsizei, const GLint *, GLenum); +GLAPI void APIENTRY glActiveVaryingNV (GLuint, const GLchar *); +GLAPI GLint APIENTRY glGetVaryingLocationNV (GLuint, const GLchar *); +GLAPI void APIENTRY glGetActiveVaryingNV (GLuint, GLuint, GLsizei, GLsizei *, GLsizei *, GLenum *, GLchar *); +GLAPI void APIENTRY glGetTransformFeedbackVaryingNV (GLuint, GLuint, GLint *); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLBEGINTRANSFORMFEEDBACKNVPROC) (GLenum primitiveMode); +typedef void (APIENTRYP PFNGLENDTRANSFORMFEEDBACKNVPROC) (void); +typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC) (GLuint count, const GLint *attribs, GLenum bufferMode); +typedef void (APIENTRYP PFNGLBINDBUFFERRANGENVPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +typedef void (APIENTRYP PFNGLBINDBUFFEROFFSETNVPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset); +typedef void (APIENTRYP PFNGLBINDBUFFERBASENVPROC) (GLenum target, GLuint index, GLuint buffer); +typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC) (GLuint program, GLsizei count, const GLint *locations, GLenum bufferMode); +typedef void (APIENTRYP PFNGLACTIVEVARYINGNVPROC) (GLuint program, const GLchar *name); +typedef GLint (APIENTRYP PFNGLGETVARYINGLOCATIONNVPROC) (GLuint program, const GLchar *name); +typedef void (APIENTRYP PFNGLGETACTIVEVARYINGNVPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); +typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC) (GLuint program, GLuint index, GLint *location); +#endif + +#ifndef GL_EXT_bindable_uniform +#define GL_EXT_bindable_uniform 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glUniformBufferEXT (GLuint, GLint, GLuint); +GLAPI GLint APIENTRY glGetUniformBufferSizeEXT (GLuint, GLint); +GLAPI GLintptr APIENTRY glGetUniformOffsetEXT (GLuint, GLint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLUNIFORMBUFFEREXTPROC) (GLuint program, GLint location, GLuint buffer); +typedef GLint (APIENTRYP PFNGLGETUNIFORMBUFFERSIZEEXTPROC) (GLuint program, GLint location); +typedef GLintptr (APIENTRYP PFNGLGETUNIFORMOFFSETEXTPROC) (GLuint program, GLint location); +#endif + +#ifndef GL_EXT_texture_integer +#define GL_EXT_texture_integer 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTexParameterIivEXT (GLenum, GLenum, const GLint *); +GLAPI void APIENTRY glTexParameterIuivEXT (GLenum, GLenum, const GLuint *); +GLAPI void APIENTRY glGetTexParameterIivEXT (GLenum, GLenum, GLint *); +GLAPI void APIENTRY glGetTexParameterIuivEXT (GLenum, GLenum, GLuint *); +GLAPI void APIENTRY glClearColorIiEXT (GLint, GLint, GLint, GLint); +GLAPI void APIENTRY glClearColorIuiEXT (GLuint, GLuint, GLuint, GLuint); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, const GLuint *params); +typedef void (APIENTRYP PFNGLGETTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, GLuint *params); +typedef void (APIENTRYP PFNGLCLEARCOLORIIEXTPROC) (GLint red, GLint green, GLint blue, GLint alpha); +typedef void (APIENTRYP PFNGLCLEARCOLORIUIEXTPROC) (GLuint red, GLuint green, GLuint blue, GLuint alpha); +#endif + #ifdef __cplusplus } From 2b94829b1237e5a7947d597f945b6f248df2e4a9 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Fri, 18 Jun 2021 23:50:24 +0300 Subject: [PATCH 089/606] SDL_opengl.h: upgrade glext part to v40 (updates some cpp checks.) SDL-1.2 and sdl12-compat versions are fully in sync now. --- include/SDL/SDL_opengl.h | 49 +++++++++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 18 deletions(-) diff --git a/include/SDL/SDL_opengl.h b/include/SDL/SDL_opengl.h index 000c87336..1a33a905e 100644 --- a/include/SDL/SDL_opengl.h +++ b/include/SDL/SDL_opengl.h @@ -23,8 +23,10 @@ functionality to let you build an SDL-1.2-based project without having the real SDL-1.2 available to you. */ -/* This file is a verbatim copy of SDL 1.2's, the only exceptions being -doxygen comments and MacOS Classic #include fixes - both removed here. */ +/* This file is a verbatim copy of SDL 1.2's, except for the + MacOS Classic include fixes being removed. */ + +/* This is a simple file to encapsulate the OpenGL API headers */ #include "SDL_config.h" @@ -33,27 +35,28 @@ doxygen comments and MacOS Classic #include fixes - both removed here. */ #define WIN32_LEAN_AND_MEAN #endif #ifndef NOMINMAX -#define NOMINMAX /* Don't defined min() and max() */ +#define NOMINMAX /* Don't define min() and max() */ #endif #include #endif #ifndef NO_SDL_GLEXT -#define __glext_h_ /* Don't let gl.h include glext.h */ -#define __gl_glext_h_ /* Don't let gl.h include glext.h */ +#define __glext_h_ /* Don't let gl.h include glext.h */ +#define __gl_glext_h_ /* Don't let gl.h include glext.h */ #endif #if defined(__MACOSX__) -#include /* Header File For The OpenGL Library */ -#include /* Header File For The GLU Library */ +#include /* Header File For The OpenGL Library */ +#include /* Header File For The GLU Library */ #else -#include /* Header File For The OpenGL Library */ -#include /* Header File For The GLU Library */ +#include /* Header File For The OpenGL Library */ +#include /* Header File For The GLU Library */ #endif #ifndef NO_SDL_GLEXT #undef __glext_h_ #undef __gl_glext_h_ #endif -/* This is included here because glext.h is not available on some systems. +/** glext.h + * This is included here because glext.h is not available on some systems. * If you don't want this version included, simply define "NO_SDL_GLEXT" */ #ifndef NO_SDL_GLEXT @@ -106,9 +109,9 @@ extern "C" { /*************************************************************/ /* Header file version number, required by OpenGL ABI for Linux */ -/* glext.h last updated 2007/02/12 */ +/* glext.h last updated 2008/03/24 */ /* Current version at http://www.opengl.org/registry/ */ -#define GL_GLEXT_VERSION 39 +#define GL_GLEXT_VERSION 40 #ifndef GL_VERSION_1_2 #define GL_UNSIGNED_BYTE_3_3_2 0x8032 @@ -3151,8 +3154,8 @@ extern "C" { #ifndef GL_EXT_framebuffer_blit #define GL_READ_FRAMEBUFFER_EXT 0x8CA8 #define GL_DRAW_FRAMEBUFFER_EXT 0x8CA9 -#define GL_READ_FRAMEBUFFER_BINDING_EXT 0x8CAA #define GL_DRAW_FRAMEBUFFER_BINDING_EXT GL_FRAMEBUFFER_BINDING_EXT +#define GL_READ_FRAMEBUFFER_BINDING_EXT 0x8CAA #endif #ifndef GL_EXT_framebuffer_multisample @@ -3439,6 +3442,9 @@ extern "C" { #define GL_RGBA_INTEGER_MODE_EXT 0x8D9E #endif +#ifndef GL_GREMEDY_frame_terminator +#endif + /*************************************************************/ @@ -3490,16 +3496,16 @@ typedef unsigned short GLhalfNV; #endif #ifndef GLEXT_64_TYPES_DEFINED -/* This code block is duplicated in glext.h, so must be protected */ +/* This code block is duplicated in glxext.h, so must be protected */ #define GLEXT_64_TYPES_DEFINED /* Define int32_t, int64_t, and uint64_t types for UST/MSC */ /* (as used in the GL_EXT_timer_query extension). */ #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L #include -#elif defined(__sun__) +#elif defined(__sun__) || defined(__digital__) #include #if defined(__STDC__) -#if defined(__arch64__) +#if defined(__arch64__) || defined(_LP64) typedef long int int64_t; typedef unsigned long int uint64_t; #else @@ -3507,7 +3513,7 @@ typedef long long int int64_t; typedef unsigned long long int uint64_t; #endif /* __arch64__ */ #endif /* __STDC__ */ -#elif defined( __VMS ) +#elif defined( __VMS ) || defined(__sgi) #include #elif defined(__SCO__) || defined(__USLC__) #include @@ -7328,6 +7334,14 @@ typedef void (APIENTRYP PFNGLCLEARCOLORIIEXTPROC) (GLint red, GLint green, GLint typedef void (APIENTRYP PFNGLCLEARCOLORIUIEXTPROC) (GLuint red, GLuint green, GLuint blue, GLuint alpha); #endif +#ifndef GL_GREMEDY_frame_terminator +#define GL_GREMEDY_frame_terminator 1 +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glFrameTerminatorGREMEDY (void); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (APIENTRYP PFNGLFRAMETERMINATORGREMEDYPROC) (void); +#endif + #ifdef __cplusplus } @@ -7335,4 +7349,3 @@ typedef void (APIENTRYP PFNGLCLEARCOLORIUIEXTPROC) (GLuint red, GLuint green, GL #endif /* GL_GLEXT_LEGACY */ #endif /* NO_SDL_GLEXT */ - From 4ad7ba6348d08d75496362efab1cbf099a6de42d Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sat, 19 Jun 2021 12:38:26 -0400 Subject: [PATCH 090/606] SDL_syswm.h only includes X11 headers if __has_include can find it. This isn't a heavily-used feature of SDL 1.2 in general, but we can't promise X11 is available in a generic sense (we can check for common Windows defines before including windows.h, but common Unix platforms may or may not have Xlib available). In the name of avoiding a configure stage for the headers, we're saying this only works if we're on a Unix platform (even if X11 is available elsewhere!) and if the compiler has __has_include support (GCC 5+, Clang, etc). Note that sdl12-compat itself doesn't currently pass on X11 syswm events, etc, so it might just be worth dumping this completely and calling apps that rely on it unsupported...it's entirely possible a given copy of the headers wouldn't support it in real 1.2, too. --- include/SDL/SDL_syswm.h | 63 +++++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 31 deletions(-) diff --git a/include/SDL/SDL_syswm.h b/include/SDL/SDL_syswm.h index 6079a9b4f..dc645c827 100644 --- a/include/SDL/SDL_syswm.h +++ b/include/SDL/SDL_syswm.h @@ -32,41 +32,16 @@ real SDL-1.2 available to you. */ #ifndef SDL_PROTOTYPES_ONLY -# if defined(__WIN32__) -# ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN +# if defined(unix) && !defined(__APPLE__) && defined(__has_include) +# if __has_include() +# define SDL12_COMPAT_SUPPORT_SYSWM_X11 1 # endif -# include - -# include "begin_code.h" - - typedef struct SDL_SysWMmsg - { - SDL_version version; - HWND hwnd; - UINT msg; - WPARAM wParam; - LPARAM lParam; - } SDL_SysWMmsg; - - typedef struct SDL_SysWMinfo { - SDL_version version; - HWND window; - HGLRC hglrc; - } SDL_SysWMinfo; - -# include "close_code.h" - -# elif defined(unix) /* shrug */ +# endif -# ifdef __APPLE__ -# define Cursor X11Cursor -# endif +# if defined(SDL12_COMPAT_SUPPORT_SYSWM_X11) +# undef SDL12_COMPAT_SUPPORT_SYSWM_X11 # include # include -# ifdef __APPLE__ -# undef Cursor -# endif # include "begin_code.h" @@ -102,6 +77,32 @@ real SDL-1.2 available to you. */ } SDL_SysWMinfo; # include "close_code.h" + +# elif defined(__WIN32__) +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +# endif +# include + +# include "begin_code.h" + + typedef struct SDL_SysWMmsg + { + SDL_version version; + HWND hwnd; + UINT msg; + WPARAM wParam; + LPARAM lParam; + } SDL_SysWMmsg; + + typedef struct SDL_SysWMinfo { + SDL_version version; + HWND window; + HGLRC hglrc; + } SDL_SysWMinfo; + +# include "close_code.h" + # else # include "begin_code.h" From 4f3dde88a2475b2a42df18a9784a81656edc05b0 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 21 Jun 2021 22:57:01 -0400 Subject: [PATCH 091/606] SDL_VideoModeOK: report 32 bpp if the display is actually 24. This appears to be how apps expect SDL 1.2 to report here. Fixes assertion failure in enigma. --- src/SDL12_compat.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 7c7fc09ab..0593abc76 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -3456,24 +3456,25 @@ SDL_VideoModeOK(int width, int height, int bpp, Uint32 sdl12flags) if (!(sdl12flags & SDL12_FULLSCREEN)) { SDL_DisplayMode mode; SDL20_GetDesktopDisplayMode(VideoDisplayIndex, &mode); - return SDL_BITSPERPIXEL(mode.format); - } - - for (i = 0; i < VideoModesCount; ++i) { - VideoModeList *vmode = &VideoModes[i]; - for (j = 0; j < vmode->nummodes; ++j) { - if (vmode->modeslist12[j].w == width && vmode->modeslist12[j].h == height) - { - if (!vmode->format) { - return bpp; - } - if (SDL_BITSPERPIXEL(vmode->format) >= (Uint32) bpp) { - actual_bpp = SDL_BITSPERPIXEL(vmode->format); + actual_bpp = SDL_BITSPERPIXEL(mode.format); + } else { + for (i = 0; i < VideoModesCount; ++i) { + VideoModeList *vmode = &VideoModes[i]; + for (j = 0; j < vmode->nummodes; ++j) { + if (vmode->modeslist12[j].w == width && vmode->modeslist12[j].h == height) + { + if (!vmode->format) { + return bpp; + } + if (SDL_BITSPERPIXEL(vmode->format) >= (Uint32) bpp) { + actual_bpp = SDL_BITSPERPIXEL(vmode->format); + } } } } } - return actual_bpp; + + return (actual_bpp == 24) ? 32 : actual_bpp; } DECLSPEC SDL12_Rect ** SDLCALL From a9ec24879251cf1ba98e309b3c3cc031a7d74e37 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 21 Jun 2021 22:58:04 -0400 Subject: [PATCH 092/606] Surface20to12: don't calculate SDL_SRCALPHA and then lose it. (we were SDL_zerop'ing the struct after setting this field, whoops.) Fixes rendering issues in enigma. Fixes #112. --- src/SDL12_compat.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 0593abc76..ee352a35a 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -3097,7 +3097,7 @@ Rect12to20(const SDL12_Rect *rect12, SDL_Rect *rect20) static SDL12_Surface * Surface20to12(SDL_Surface *surface20) { - SDL_BlendMode blendmode; + SDL_BlendMode blendmode = SDL_BLENDMODE_NONE; SDL12_Surface *surface12 = NULL; SDL12_Palette *palette12 = NULL; SDL12_PixelFormat *format12 = NULL; @@ -3163,11 +3163,6 @@ Surface20to12(SDL_Surface *surface20) format12->alpha = 255; } - blendmode = SDL_BLENDMODE_NONE; - if ((SDL20_GetSurfaceBlendMode(surface20, &blendmode) == 0) && (blendmode == SDL_BLENDMODE_BLEND)) { - surface12->flags |= SDL12_SRCALPHA; - } - SDL20_zerop(surface12); flags = surface20->flags; flags &= ~SDL_SIMD_ALIGNED; /* we don't need to map this to 1.2 */ @@ -3178,6 +3173,10 @@ Surface20to12(SDL_Surface *surface20) #undef MAPSURFACEFLAGS SDL_assert(flags == 0); /* non-zero if there's a flag we didn't map. */ + if ((SDL20_GetSurfaceBlendMode(surface20, &blendmode) == 0) && (blendmode == SDL_BLENDMODE_BLEND)) { + surface12->flags |= SDL12_SRCALPHA; + } + surface12->format = format12; surface12->w = surface20->w; surface12->h = surface20->h; From e20b7fc8fe7a17caeb360fd85b19c598bf0c32fb Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 22 Jun 2021 00:09:41 -0400 Subject: [PATCH 093/606] Apparently g++'s preprocessor defines __unix__ but not unix. :/ Fixes lincity-ng failing to compile with the replacement headers because iconv wasn't set up correctly. --- include/SDL/SDL_config.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/SDL/SDL_config.h b/include/SDL/SDL_config.h index 1a71bc09a..56cbbe5ab 100644 --- a/include/SDL/SDL_config.h +++ b/include/SDL/SDL_config.h @@ -72,7 +72,7 @@ stage, though. Send patches if your platform lacks something. */ #define HAVE_MATH_H 1 #endif -#if defined(unix) || defined(__APPLE__) +#if defined(unix) || defined(__unix__) || defined(__APPLE__) #define HAVE_ICONV_H 1 #define HAVE_SIGNAL_H 1 #endif @@ -156,7 +156,7 @@ stage, though. Send patches if your platform lacks something. */ #define HAVE_SEM_TIMEDWAIT 1 #endif -#if defined(unix) || defined(__APPLE__) +#if defined(unix) || defined(__unix__) || defined(__APPLE__) #define HAVE_ICONV 1 #define HAVE_SIGACTION 1 #define HAVE_SA_SIGACTION 1 From 96c74584d7b04007f8869e3f299b62d29c86abbb Mon Sep 17 00:00:00 2001 From: David Gow Date: Tue, 22 Jun 2021 14:09:33 +0800 Subject: [PATCH 094/606] Don't set {R,G,B,A}masks on SDL2 paletted surfaces SDL2 expects 8-bit surfaces to have correct {R,G,B,A}masks in their format: either all 0 for paletted surfaces, or the correct values for SDL_PIXELFORMAT_RGB332. Indeed, SDL_ConvertSurface() will crash if this is not the case. Some SDL 1.2 applications provide incorrect masks for paletted surfaces. We originally zeroed these out in 46fdbf7c1d, but 3af751b91b actually re-sets these in SetPalette12ForMasks(). Instead, do not set the masks on the SDL 2 surface in SetPalette12ForMasks(), and force them to be 0 in PixelFormat12to20() if there is a palette. The masks are still set on the SDL 1.2 surface's format, and the palette generated by SetPalette12ForMasks() should in theory make sure surfaces with 8-bit masks still work. This fixes a crash on startup in circuslinux: http://www.newbreedsoftware.com/circus-linux/ --- src/SDL12_compat.c | 52 ++++++++++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 23 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index ee352a35a..e3336781e 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1415,18 +1415,35 @@ PixelFormat12to20(SDL_PixelFormat *format20, SDL_Palette *palette20, const SDL12 format20->format = SDL20_MasksToPixelFormatEnum(format12->BitsPerPixel, format12->Rmask, format12->Gmask, format12->Bmask, format12->Amask); format20->BitsPerPixel = format12->BitsPerPixel; format20->BytesPerPixel = format12->BytesPerPixel; - format20->Rmask = format12->Rmask; - format20->Gmask = format12->Gmask; - format20->Bmask = format12->Bmask; - format20->Amask = format12->Amask; - format20->Rloss = format12->Rloss; - format20->Gloss = format12->Gloss; - format20->Bloss = format12->Bloss; - format20->Aloss = format12->Aloss; - format20->Rshift = format12->Rshift; - format20->Gshift = format12->Gshift; - format20->Bshift = format12->Bshift; - format20->Ashift = format12->Ashift; + + /* Paletted surfaces shouldn't have masks in SDL 2.0 */ + if (format12->palette) { + format20->Rmask = 0; + format20->Gmask = 0; + format20->Bmask = 0; + format20->Amask = 0; + format20->Rloss = 8; + format20->Gloss = 8; + format20->Bloss = 8; + format20->Aloss = 8; + format20->Rshift = 0; + format20->Gshift = 0; + format20->Bshift = 0; + format20->Ashift = 0; + } else { + format20->Rmask = format12->Rmask; + format20->Gmask = format12->Gmask; + format20->Bmask = format12->Bmask; + format20->Amask = format12->Amask; + format20->Rloss = format12->Rloss; + format20->Gloss = format12->Gloss; + format20->Bloss = format12->Bloss; + format20->Aloss = format12->Aloss; + format20->Rshift = format12->Rshift; + format20->Gshift = format12->Gshift; + format20->Bshift = format12->Bshift; + format20->Ashift = format12->Ashift; + } format20->refcount = 1; format20->next = NULL; return format20; @@ -3200,7 +3217,6 @@ static void SetPalette12ForMasks(SDL12_Surface *surface12, const Uint32 Rmask, const Uint32 Gmask, const Uint32 Bmask) { SDL12_PixelFormat *format12; - SDL_PixelFormat * format20; SDL_Color *color; int i, ncolors; @@ -3258,16 +3274,6 @@ SetPalette12ForMasks(SDL12_Surface *surface12, const Uint32 Rmask, const Uint32 color->a = 255; } - format20 = surface12->surface20->format; - #define UPDATEFMT20(t) \ - format20->t##mask = format12->t##mask; \ - format20->t##loss = format12->t##loss; \ - format20->t##shift = format12->t##shift; - UPDATEFMT20(R); - UPDATEFMT20(G); - UPDATEFMT20(B); - UPDATEFMT20(A); - #undef UPDATEFMT20 } } From 2fd4922bc2012c542d967960849a5087f01463bd Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Tue, 22 Jun 2021 15:50:50 +0300 Subject: [PATCH 095/606] replaced all unix preprocessor checks with __unix__ --- include/SDL/SDL_config.h | 4 ++-- include/SDL/SDL_syswm.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/SDL/SDL_config.h b/include/SDL/SDL_config.h index 56cbbe5ab..6ab8c8799 100644 --- a/include/SDL/SDL_config.h +++ b/include/SDL/SDL_config.h @@ -72,7 +72,7 @@ stage, though. Send patches if your platform lacks something. */ #define HAVE_MATH_H 1 #endif -#if defined(unix) || defined(__unix__) || defined(__APPLE__) +#if defined(__unix__) || defined(__APPLE__) #define HAVE_ICONV_H 1 #define HAVE_SIGNAL_H 1 #endif @@ -156,7 +156,7 @@ stage, though. Send patches if your platform lacks something. */ #define HAVE_SEM_TIMEDWAIT 1 #endif -#if defined(unix) || defined(__unix__) || defined(__APPLE__) +#if defined(__unix__) || defined(__APPLE__) #define HAVE_ICONV 1 #define HAVE_SIGACTION 1 #define HAVE_SA_SIGACTION 1 diff --git a/include/SDL/SDL_syswm.h b/include/SDL/SDL_syswm.h index dc645c827..b6b0c9e5b 100644 --- a/include/SDL/SDL_syswm.h +++ b/include/SDL/SDL_syswm.h @@ -32,7 +32,7 @@ real SDL-1.2 available to you. */ #ifndef SDL_PROTOTYPES_ONLY -# if defined(unix) && !defined(__APPLE__) && defined(__has_include) +# if defined(__unix__) && !defined(__APPLE__) && defined(__has_include) # if __has_include() # define SDL12_COMPAT_SUPPORT_SYSWM_X11 1 # endif From ffc3d7993ec3f32cf5eadf925343aa1b7d90629c Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Tue, 22 Jun 2021 15:55:00 +0300 Subject: [PATCH 096/606] changed fake-cd mp3 filename format to trackXX.mp3, where XX is 01..99 --- src/SDL12_compat.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index e3336781e..deecea03b 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -6175,7 +6175,8 @@ SDL_CDNumDrives(void) warned_once = SDL_TRUE; SDL20_Log("This app is looking for CD-ROM drives, but no path was specified"); SDL20_Log("Set the SDL12COMPAT_FAKE_CDROM_PATH environment variable to a directory"); - SDL20_Log("of MP3 files named NUM.mp3, where NUM is a track number from 0 to 99"); + SDL20_Log("of MP3 files named trackXX.mp3 where XX is a track number in two digits"); + SDL20_Log("from 01 to 99"); } } @@ -6221,6 +6222,7 @@ SDL_CDOpen(int drive) SDL20_OutOfMemory(); return NULL; } + retval->numtracks = 1; /* start from track #1. */ alloclen = SDL20_strlen(CDRomPath) + 32; fullpath = (char *) SDL20_malloc(alloclen); @@ -6249,10 +6251,13 @@ SDL_CDOpen(int drive) drmp3_uint64 pcmframes; drmp3_uint32 samplerate; SDL12_CDtrack *track; + char c0, c1; /* we only report audio tracks, starting at 0... */ FIXME("Let there be fake data tracks (quake1's audio starts at track 2, etc)."); - SDL20_snprintf(fullpath, alloclen, "%s%s%d.mp3", CDRomPath, DIRSEP, retval->numtracks); + c0 = retval->numtracks / 10 + '0'; + c1 = retval->numtracks % 10 + '0'; + SDL20_snprintf(fullpath, alloclen, "%s%strack%c%c.mp3", CDRomPath, DIRSEP, c0, c1); rw = SDL20_RWFromFile(fullpath, "rb"); if (!rw) { break; /* ok, we're done looking for more. */ From 67b5a5bd7da017d3abaf646e963f1c3c9d01f82b Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Tue, 22 Jun 2021 17:50:20 +0300 Subject: [PATCH 097/606] Fake-cd numtrack fixes : - Fixed numtracks breakage from previous commit. - Allow missing track01.mp3 and interpret it a data, so long as there are actual audio tracks following it. Tested with quakespasm on Linux. --- src/SDL12_compat.c | 54 +++++++++++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 22 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index deecea03b..8daf96e0a 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -6222,7 +6222,6 @@ SDL_CDOpen(int drive) SDL20_OutOfMemory(); return NULL; } - retval->numtracks = 1; /* start from track #1. */ alloclen = SDL20_strlen(CDRomPath) + 32; fullpath = (char *) SDL20_malloc(alloclen); @@ -6251,33 +6250,37 @@ SDL_CDOpen(int drive) drmp3_uint64 pcmframes; drmp3_uint32 samplerate; SDL12_CDtrack *track; - char c0, c1; + int c; char c0, c1; - /* we only report audio tracks, starting at 0... */ - FIXME("Let there be fake data tracks (quake1's audio starts at track 2, etc)."); - c0 = retval->numtracks / 10 + '0'; - c1 = retval->numtracks % 10 + '0'; + /* we only report audio tracks, starting at 1... */ + FIXME("Let there be fake data tracks"); + c = retval->numtracks + 1; + c0 = c / 10 + '0'; + c1 = c % 10 + '0'; SDL20_snprintf(fullpath, alloclen, "%s%strack%c%c.mp3", CDRomPath, DIRSEP, c0, c1); rw = SDL20_RWFromFile(fullpath, "rb"); - if (!rw) { - break; /* ok, we're done looking for more. */ - } - - if (!drmp3_init(mp3, mp3_sdlrwops_read, mp3_sdlrwops_seek, rw, NULL)) { - SDL20_RWclose(rw); + if (!rw && c > 1) { break; /* ok, we're done looking for more. */ } - pcmframes = drmp3_get_pcm_frame_count(mp3); - samplerate = mp3->sampleRate; - FreeMp3(mp3); - track = &retval->track[retval->numtracks]; - track->id = retval->numtracks; - track->type = 0; /* audio track. Data tracks are 4. */ - track->length = (Uint32) ((((double) pcmframes) / ((double) samplerate)) * CDAUDIO_FPS); - track->offset = total_track_offset; - total_track_offset += track->length; + if (!rw) { + track->type = 4; /* data track. E.g.: quake's audio starts at track 2. */ + } else { + if (!drmp3_init(mp3, mp3_sdlrwops_read, mp3_sdlrwops_seek, rw, NULL)) { + SDL20_RWclose(rw); + break; /* ok, we're done looking for more. */ + } + pcmframes = drmp3_get_pcm_frame_count(mp3); + samplerate = mp3->sampleRate; + FreeMp3(mp3); + + track->id = retval->numtracks; + track->type = 0; /* audio track. Data tracks are 4. */ + track->length = (Uint32) ((((double) pcmframes) / ((double) samplerate)) * CDAUDIO_FPS); + track->offset = total_track_offset; + total_track_offset += track->length; + } retval->numtracks++; @@ -6285,6 +6288,9 @@ SDL_CDOpen(int drive) break; /* max tracks you can have on an audio CD. */ } } + if (retval->numtracks == 1 && retval->track[0].type != 0) { + retval->numtracks = 0; /* data-only */ + } SDL20_free(mp3); SDL20_free(fullpath); @@ -6363,12 +6369,16 @@ LoadCDTrack(const int tracknum, drmp3 *mp3) SDL_RWops *rw = NULL; const size_t alloclen = SDL20_strlen(CDRomPath) + 32; char *fullpath = (char *) SDL_malloc(alloclen); + const int c = tracknum + 1; + char c0, c1; if (!fullpath) { return SDL_FALSE; } - SDL20_snprintf(fullpath, alloclen, "%s%s%d.mp3", CDRomPath, DIRSEP, tracknum); + c0 = c / 10 + '0'; + c1 = c % 10 + '0'; + SDL20_snprintf(fullpath, alloclen, "%s%strack%c%c.mp3", CDRomPath, DIRSEP, c0, c1); rw = SDL20_RWFromFile(fullpath, "rb"); SDL20_free(fullpath); From ea08a24b3f5eba381c0ce962914c76106116eeaa Mon Sep 17 00:00:00 2001 From: David Gow Date: Tue, 22 Jun 2021 20:53:03 +0800 Subject: [PATCH 098/606] SDL_PauseAudio should work within the callback In SDL 1.2, SDL_PauseAudio() works from within the audio callback, whereas currently in sdl12-compat, it deadlocks due to SDL_LockAudio() being called. Move the callback paused state out of the callback structure (whose allocation is protected by SDL_LockAudio()) and into a separate atomic variable. SDL_PauseAudio() can then simply set that value. This fixes some SDL 1.2 Ren'py games, which will deadlock somewhat randomly either at startup or when a new piece of music plays, due to SDL_PauseAudio() being called from within the callback. --- src/SDL12_compat.c | 15 +++++---------- src/SDL20_syms.h | 3 +++ 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 8daf96e0a..f13f26d53 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -6086,7 +6086,6 @@ typedef struct SDL_AudioSpec device_format; SDL_bool app_callback_opened; - SDL_bool app_callback_paused; SDL_AudioSpec app_callback_format; SDL_AudioStream *app_callback_stream; @@ -6107,7 +6106,7 @@ typedef struct } AudioCallbackWrapperData; static AudioCallbackWrapperData *audio_cbdata = NULL; - +static SDL_atomic_t audio_callback_paused; static void @@ -6721,7 +6720,7 @@ AudioCallbackWrapper(void *userdata, Uint8 *stream, int len) AudioCallbackWrapperData *data = (AudioCallbackWrapperData *) userdata; SDL_bool must_mix = SDL_FALSE; - if (data->app_callback_opened && !data->app_callback_paused) { + if (data->app_callback_opened && !SDL20_AtomicGet(&audio_callback_paused)) { while (SDL20_AudioStreamAvailable(data->app_callback_stream) < len) { SDL20_memset(data->mix_buffer, data->app_callback_format.silence, data->app_callback_format.size); /* SDL2 doesn't clear the stream before calling in here, but 1.2 expects it. */ data->app_callback_format.callback(data->app_callback_format.userdata, data->mix_buffer, data->app_callback_format.size); @@ -6903,7 +6902,7 @@ SDL_OpenAudio(SDL_AudioSpec *want, SDL_AudioSpec *obtained) SDL20_memcpy(&audio_cbdata->app_callback_format, want, sizeof (SDL_AudioSpec)); audio_cbdata->app_callback_opened = SDL_TRUE; - audio_cbdata->app_callback_paused = SDL_TRUE; /* app callback always starts paused after open. */ + SDL20_AtomicSet(&audio_callback_paused, SDL_TRUE); /* app callback always starts paused after open. */ FIXME("Cleanup from failures in here"); SDL_assert(audio_cbdata->app_callback_stream == NULL); @@ -6921,11 +6920,7 @@ SDL_OpenAudio(SDL_AudioSpec *want, SDL_AudioSpec *obtained) DECLSPEC void SDLCALL SDL_PauseAudio(int pause_on) { - SDL20_LockAudio(); - if (audio_cbdata && audio_cbdata->app_callback_opened) { - audio_cbdata->app_callback_paused = pause_on ? SDL_TRUE : SDL_FALSE; - } - SDL20_UnlockAudio(); + SDL20_AtomicSet(&audio_callback_paused, pause_on ? SDL_TRUE : SDL_FALSE); } DECLSPEC SDL_AudioStatus SDLCALL @@ -6934,7 +6929,7 @@ SDL_GetAudioStatus(void) SDL_AudioStatus retval = SDL_AUDIO_STOPPED; SDL20_LockAudio(); if (audio_cbdata && audio_cbdata->app_callback_opened) { - retval = audio_cbdata->app_callback_paused ? SDL_AUDIO_PAUSED : SDL_AUDIO_PLAYING; + retval = SDL20_AtomicGet(&audio_callback_paused) ? SDL_AUDIO_PAUSED : SDL_AUDIO_PLAYING; } SDL20_UnlockAudio(); return retval; diff --git a/src/SDL20_syms.h b/src/SDL20_syms.h index baf6a024d..0937d8ac7 100644 --- a/src/SDL20_syms.h +++ b/src/SDL20_syms.h @@ -188,6 +188,9 @@ SDL20_SYM_PASSTHROUGH(int,CondBroadcast,(SDL_cond *a),(a),return) SDL20_SYM_PASSTHROUGH(int,CondWait,(SDL_cond *a, SDL_mutex *b),(a,b),return) SDL20_SYM_PASSTHROUGH(int,CondWaitTimeout,(SDL_cond *a, SDL_mutex *b, Uint32 c),(a,b,c),return) +SDL20_SYM(int,AtomicGet,(SDL_atomic_t *a),(a),return) +SDL20_SYM(void,AtomicSet,(SDL_atomic_t *a, int b),(a,b),) + SDL20_SYM(SDL_AudioSpec *,LoadWAV_RW,(SDL_RWops *a, int b, SDL_AudioSpec *c, Uint8 **d, Uint32 *e),(a,b,c,d,e),return) SDL20_SYM(int,OpenAudio,(SDL_AudioSpec *a, SDL_AudioSpec *b),(a,b),return) SDL20_SYM(void,CloseAudio,(void),(),) From 44d8d29e4f54f126a6e939db1be1bdd93c042862 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 22 Jun 2021 14:48:58 -0400 Subject: [PATCH 099/606] Initial shot at SDLmain. Mostly just the public domain code from SDL 1.2. --- CMakeLists.txt | 25 +- include/SDL/SDL_main.h | 1 + src/SDLmain/dummy/SDL_dummy_main.c | 13 + src/SDLmain/macosx/SDLMain.h | 16 ++ src/SDLmain/macosx/SDLMain.m | 402 +++++++++++++++++++++++++++++ src/SDLmain/win32/SDL_win32_main.c | 402 +++++++++++++++++++++++++++++ src/SDLmain/win32/version.rc | 38 +++ 7 files changed, 889 insertions(+), 8 deletions(-) create mode 100644 src/SDLmain/dummy/SDL_dummy_main.c create mode 100644 src/SDLmain/macosx/SDLMain.h create mode 100644 src/SDLmain/macosx/SDLMain.m create mode 100644 src/SDLmain/win32/SDL_win32_main.c create mode 100644 src/SDLmain/win32/version.rc diff --git a/CMakeLists.txt b/CMakeLists.txt index f5587dfd8..323849dc2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -105,6 +105,16 @@ return 0; }" IS_X86) endif() +# SDLmain library... +if(APPLE) + add_library(SDLmain STATIC src/SDLmain/macosx/SDLmain.m) +elseif(WIN32) + add_library(SDLmain STATIC src/SDLmain/win32/SDL_win32_main.c src/SDLmain/win32/version.rc) +else() + add_library(SDLmain STATIC src/SDLmain/dummy/SDL_dummy_main.c) +endif() +target_include_directories(SDLmain PRIVATE "include/SDL") + if(SDL12TESTS) if(NOT (WIN32 OR APPLE OR CYGWIN OR HAIKU OR BEOS)) find_library(MATH_LIBRARY m) @@ -125,12 +135,13 @@ if(SDL12TESTS) macro(test_program _NAME _SRCS) add_executable(${_NAME} ${_SRCS}) target_include_directories(${_NAME} PRIVATE "include/SDL") - target_link_libraries(${_NAME} SDL) + target_link_libraries(${_NAME} SDL SDLmain) # Turn off MSVC's aggressive C runtime warnings for the old test programs. if(MSVC) set_target_properties(${_NAME} PROPERTIES COMPILE_DEFINITIONS "${HAVE_OPENGL_DEFINE};_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE") elseif(APPLE) set_target_properties(${_NAME} PROPERTIES COMPILE_DEFINITIONS "${HAVE_OPENGL_DEFINE};GL_SILENCE_DEPRECATION=1") + target_link_libraries(${_NAME} "-Wl,-framework,Cocoa") else() set_target_properties(${_NAME} PROPERTIES COMPILE_DEFINITIONS "${HAVE_OPENGL_DEFINE}") endif() @@ -184,7 +195,7 @@ if(SDL12TESTS) endforeach(fname) endif() -install(TARGETS SDL +install(TARGETS SDL SDLmain LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} @@ -197,15 +208,13 @@ if(SDL12DEVEL) if(NOT MSVC) if(WIN32) - # FIXME: no SDL_main for Windows! - set(SDL_CFLAGS "") # -Dmain=SDL_main + set(SDL_CFLAGS "") set(SDL_RLD_FLAGS "") - set(SDL_LIBS "-lSDL -mwindows") # -lmingw32 -lSDLmain -lSDL -mwindows + set(SDL_LIBS "-lSDLmain -lSDL -mwindows") # -lmingw32 -lSDL -mwindows set(SDL_STATIC_LIBS "") elseif(APPLE) - # FIXME: no SDL_main for Mac! - set(SDL_CFLAGS "-D_THREAD_SAFE") # -Dmain=SDL_main - set(SDL_LIBS "-lSDL") # -lSDLmain + set(SDL_CFLAGS "-D_THREAD_SAFE") + set(SDL_LIBS "-lSDLmain -lSDL -Wl,-framework,Cocoa") set(SDL_STATIC_LIBS "") set(SDL_RLD_FLAGS "") # !!! FIXME: this forces rpath, which we might want? else() # unix diff --git a/include/SDL/SDL_main.h b/include/SDL/SDL_main.h index 0037f55af..86052a651 100644 --- a/include/SDL/SDL_main.h +++ b/include/SDL/SDL_main.h @@ -31,6 +31,7 @@ real SDL-1.2 available to you. */ #include "begin_code.h" #if defined(__WIN32__) || defined(__MACOSX__) +#define main SDL_main extern int SDL_main(int argc, char *argv[]); #endif diff --git a/src/SDLmain/dummy/SDL_dummy_main.c b/src/SDLmain/dummy/SDL_dummy_main.c new file mode 100644 index 000000000..da47d06a8 --- /dev/null +++ b/src/SDLmain/dummy/SDL_dummy_main.c @@ -0,0 +1,13 @@ + +/* Include the SDL main definition header */ +#include "SDL_main.h" + +#ifdef main +#undef main +int main(int argc, char *argv[]) +{ + return(SDL_main(argc, argv)); +} +#else +/* Nothing to do on this platform */ +#endif diff --git a/src/SDLmain/macosx/SDLMain.h b/src/SDLmain/macosx/SDLMain.h new file mode 100644 index 000000000..c56d90cbe --- /dev/null +++ b/src/SDLmain/macosx/SDLMain.h @@ -0,0 +1,16 @@ +/* SDLMain.m - main entry point for our Cocoa-ized SDL app + Initial Version: Darrell Walisser + Non-NIB-Code & other changes: Max Horn + + Feel free to customize this file to suit your needs +*/ + +#ifndef _SDLMain_h_ +#define _SDLMain_h_ + +#import + +@interface SDLMain : NSObject +@end + +#endif /* _SDLMain_h_ */ diff --git a/src/SDLmain/macosx/SDLMain.m b/src/SDLmain/macosx/SDLMain.m new file mode 100644 index 000000000..07d392eef --- /dev/null +++ b/src/SDLmain/macosx/SDLMain.m @@ -0,0 +1,402 @@ +/* SDLMain.m - main entry point for our Cocoa-ized SDL app + Initial Version: Darrell Walisser + Non-NIB-Code & other changes: Max Horn + + Feel free to customize this file to suit your needs +*/ + +#include "SDL.h" +#include "SDLMain.h" +#include /* for MAXPATHLEN */ +#include + +/* For some reaon, Apple removed setAppleMenu from the headers in 10.4, + but the method still is there and works. To avoid warnings, we declare + it ourselves here. */ +@interface NSApplication(SDL_Missing_Methods) +- (void)setAppleMenu:(NSMenu *)menu; +@end + +/* Use this flag to determine whether we use SDLMain.nib or not */ +#define SDL_USE_NIB_FILE 0 + +/* Use this flag to determine whether we use CPS (docking) or not */ +#define SDL_USE_CPS 1 +#ifdef SDL_USE_CPS +/* Portions of CPS.h */ +typedef struct CPSProcessSerNum +{ + UInt32 lo; + UInt32 hi; +} CPSProcessSerNum; + +extern OSErr CPSGetCurrentProcess( CPSProcessSerNum *psn); +extern OSErr CPSEnableForegroundOperation( CPSProcessSerNum *psn, UInt32 _arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5); +extern OSErr CPSSetFrontProcess( CPSProcessSerNum *psn); + +#endif /* SDL_USE_CPS */ + +static int gArgc; +static char **gArgv; +static BOOL gFinderLaunch; +static BOOL gCalledAppMainline = FALSE; + +static NSString *getApplicationName(void) +{ + const NSDictionary *dict; + NSString *appName = 0; + + /* Determine the application name */ + dict = (const NSDictionary *)CFBundleGetInfoDictionary(CFBundleGetMainBundle()); + if (dict) + appName = [dict objectForKey: @"CFBundleName"]; + + if (![appName length]) + appName = [[NSProcessInfo processInfo] processName]; + + return appName; +} + +#if SDL_USE_NIB_FILE +/* A helper category for NSString */ +@interface NSString (ReplaceSubString) +- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString; +@end +#endif + +@interface NSApplication (SDLApplication) +@end + +@implementation NSApplication (SDLApplication) +/* Invoked from the Quit menu item */ +- (void)terminate:(id)sender +{ + /* Post a SDL_QUIT event */ + SDL_Event event; + event.type = SDL_QUIT; + SDL_PushEvent(&event); +} +@end + +/* The main class of the application, the application's delegate */ +@implementation SDLMain + +/* Set the working directory to the .app's parent directory */ +- (void) setupWorkingDirectory:(BOOL)shouldChdir +{ + if (shouldChdir) + { + char parentdir[MAXPATHLEN]; + CFURLRef url = CFBundleCopyBundleURL(CFBundleGetMainBundle()); + CFURLRef url2 = CFURLCreateCopyDeletingLastPathComponent(0, url); + if (CFURLGetFileSystemRepresentation(url2, 1, (UInt8 *)parentdir, MAXPATHLEN)) { + chdir(parentdir); /* chdir to the binary app's parent */ + } + CFRelease(url); + CFRelease(url2); + } +} + +#if SDL_USE_NIB_FILE + +/* Fix menu to contain the real app name instead of "SDL App" */ +- (void)fixMenu:(NSMenu *)aMenu withAppName:(NSString *)appName +{ + NSRange aRange; + NSEnumerator *enumerator; + NSMenuItem *menuItem; + + aRange = [[aMenu title] rangeOfString:@"SDL App"]; + if (aRange.length != 0) + [aMenu setTitle: [[aMenu title] stringByReplacingRange:aRange with:appName]]; + + enumerator = [[aMenu itemArray] objectEnumerator]; + while ((menuItem = [enumerator nextObject])) + { + aRange = [[menuItem title] rangeOfString:@"SDL App"]; + if (aRange.length != 0) + [menuItem setTitle: [[menuItem title] stringByReplacingRange:aRange with:appName]]; + if ([menuItem hasSubmenu]) + [self fixMenu:[menuItem submenu] withAppName:appName]; + } +} + +#else + +static void setApplicationMenu(void) +{ + /* warning: this code is very odd */ + NSMenu *appleMenu; + NSMenuItem *menuItem; + NSString *title; + NSString *appName; + + appName = getApplicationName(); + appleMenu = [[NSMenu alloc] initWithTitle:@""]; + + /* Add menu items */ + title = [@"About " stringByAppendingString:appName]; + [appleMenu addItemWithTitle:title action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""]; + + [appleMenu addItem:[NSMenuItem separatorItem]]; + + title = [@"Hide " stringByAppendingString:appName]; + [appleMenu addItemWithTitle:title action:@selector(hide:) keyEquivalent:@"h"]; + + menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"]; + [menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)]; + + [appleMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""]; + + [appleMenu addItem:[NSMenuItem separatorItem]]; + + title = [@"Quit " stringByAppendingString:appName]; + [appleMenu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@"q"]; + + + /* Put menu into the menubar */ + menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""]; + [menuItem setSubmenu:appleMenu]; + [[NSApp mainMenu] addItem:menuItem]; + + /* Tell the application object that this is now the application menu */ + [NSApp setAppleMenu:appleMenu]; + + /* Finally give up our references to the objects */ + [appleMenu release]; + [menuItem release]; +} + +/* Create a window menu */ +static void setupWindowMenu(void) +{ + NSMenu *windowMenu; + NSMenuItem *windowMenuItem; + NSMenuItem *menuItem; + + windowMenu = [[NSMenu alloc] initWithTitle:@"Window"]; + + /* "Minimize" item */ + menuItem = [[NSMenuItem alloc] initWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"]; + [windowMenu addItem:menuItem]; + [menuItem release]; + + /* Put menu into the menubar */ + windowMenuItem = [[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""]; + [windowMenuItem setSubmenu:windowMenu]; + [[NSApp mainMenu] addItem:windowMenuItem]; + + /* Tell the application object that this is now the window menu */ + [NSApp setWindowsMenu:windowMenu]; + + /* Finally give up our references to the objects */ + [windowMenu release]; + [windowMenuItem release]; +} + +/* Replacement for NSApplicationMain */ +static void CustomApplicationMain (int argc, char **argv) +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + SDLMain *sdlMain; + + /* Ensure the application object is initialised */ + [NSApplication sharedApplication]; + +#ifdef SDL_USE_CPS + { + CPSProcessSerNum PSN; + /* Tell the dock about us */ + if (!CPSGetCurrentProcess(&PSN)) + if (!CPSEnableForegroundOperation(&PSN,0x03,0x3C,0x2C,0x1103)) + if (!CPSSetFrontProcess(&PSN)) + [NSApplication sharedApplication]; + } +#endif /* SDL_USE_CPS */ + + /* Set up the menubar */ + [NSApp setMainMenu:[[NSMenu alloc] init]]; + setApplicationMenu(); + setupWindowMenu(); + + /* Create SDLMain and make it the app delegate */ + sdlMain = [[SDLMain alloc] init]; + [NSApp setDelegate:sdlMain]; + + /* Start the main event loop */ + [NSApp run]; + + [sdlMain release]; + [pool release]; +} + +#endif + + +/* + * Catch document open requests...this lets us notice files when the app + * was launched by double-clicking a document, or when a document was + * dragged/dropped on the app's icon. You need to have a + * CFBundleDocumentsType section in your Info.plist to get this message, + * apparently. + * + * Files are added to gArgv, so to the app, they'll look like command line + * arguments. Previously, apps launched from the finder had nothing but + * an argv[0]. + * + * This message may be received multiple times to open several docs on launch. + * + * This message is ignored once the app's mainline has been called. + */ +- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename +{ + const char *temparg; + size_t arglen; + char *arg; + char **newargv; + + if (!gFinderLaunch) /* MacOS is passing command line args. */ + return FALSE; + + if (gCalledAppMainline) /* app has started, ignore this document. */ + return FALSE; + + temparg = [filename UTF8String]; + arglen = SDL_strlen(temparg) + 1; + arg = (char *) SDL_malloc(arglen); + if (arg == NULL) + return FALSE; + + newargv = (char **) realloc(gArgv, sizeof (char *) * (gArgc + 2)); + if (newargv == NULL) + { + SDL_free(arg); + return FALSE; + } + gArgv = newargv; + + SDL_strlcpy(arg, temparg, arglen); + gArgv[gArgc++] = arg; + gArgv[gArgc] = NULL; + return TRUE; +} + + +/* Called when the internal event loop has just started running */ +- (void) applicationDidFinishLaunching: (NSNotification *) note +{ + int status; + + /* Set the working directory to the .app's parent directory */ + [self setupWorkingDirectory:gFinderLaunch]; + +#if SDL_USE_NIB_FILE + /* Set the main menu to contain the real app name instead of "SDL App" */ + [self fixMenu:[NSApp mainMenu] withAppName:getApplicationName()]; +#endif + + /* Hand off to main application code */ + gCalledAppMainline = TRUE; + status = SDL_main (gArgc, gArgv); + + /* We're done, thank you for playing */ + exit(status); +} +@end + + +@implementation NSString (ReplaceSubString) + +- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString +{ + unsigned int bufferSize; + unsigned int selfLen = [self length]; + unsigned int aStringLen = [aString length]; + unichar *buffer; + NSRange localRange; + NSString *result; + + bufferSize = selfLen + aStringLen - aRange.length; + buffer = (unichar *)NSAllocateMemoryPages(bufferSize*sizeof(unichar)); + + /* Get first part into buffer */ + localRange.location = 0; + localRange.length = aRange.location; + [self getCharacters:buffer range:localRange]; + + /* Get middle part into buffer */ + localRange.location = 0; + localRange.length = aStringLen; + [aString getCharacters:(buffer+aRange.location) range:localRange]; + + /* Get last part into buffer */ + localRange.location = aRange.location + aRange.length; + localRange.length = selfLen - localRange.location; + [self getCharacters:(buffer+aRange.location+aStringLen) range:localRange]; + + /* Build output string */ + result = [NSString stringWithCharacters:buffer length:bufferSize]; + + NSDeallocateMemoryPages(buffer, bufferSize); + + return result; +} + +@end + + + +#ifdef main +# undef main +#endif + + +static int IsRootCwd() +{ + char buf[MAXPATHLEN]; + char *cwd = getcwd(buf, sizeof (buf)); + return (cwd && (strcmp(cwd, "/") == 0)); +} + +static int IsFinderLaunch(const int argc, char **argv) +{ + /* -psn_XXX is passed if we are launched from Finder, SOMETIMES */ + if ( (argc >= 2) && (strncmp(argv[1], "-psn", 4) == 0) ) { + return 1; + } else if ((argc == 1) && IsRootCwd()) { + /* we might still be launched from the Finder; on 10.9+, you might not + get the -psn command line anymore. If there's no + command line, and if our current working directory is "/", it + might as well be a Finder launch. */ + return 1; + } + return 0; /* not a Finder launch. */ +} + +/* Main entry point to executable - should *not* be SDL_main! */ +int main (int argc, char **argv) +{ + /* Copy the arguments into a global variable */ + if (IsFinderLaunch(argc, argv)) { + gArgv = (char **) SDL_malloc(sizeof (char *) * 2); + gArgv[0] = argv[0]; + gArgv[1] = NULL; + gArgc = 1; + gFinderLaunch = YES; + } else { + int i; + gArgc = argc; + gArgv = (char **) SDL_malloc(sizeof (char *) * (argc+1)); + for (i = 0; i <= argc; i++) + gArgv[i] = argv[i]; + gFinderLaunch = NO; + } + +#if SDL_USE_NIB_FILE + NSApplicationMain (argc, argv); +#else + CustomApplicationMain (argc, argv); +#endif + return 0; +} + diff --git a/src/SDLmain/win32/SDL_win32_main.c b/src/SDLmain/win32/SDL_win32_main.c new file mode 100644 index 000000000..672b48c12 --- /dev/null +++ b/src/SDLmain/win32/SDL_win32_main.c @@ -0,0 +1,402 @@ +/* + SDL_main.c, placed in the public domain by Sam Lantinga 4/13/98 + + The WinMain function -- calls your program's main() function +*/ + +#include +#include + +#define WIN32_LEAN_AND_MEAN +#include + +#ifdef _WIN32_WCE +# define DIR_SEPERATOR TEXT("\\") +# undef _getcwd +# define _getcwd(str,len) wcscpy(str,TEXT("")) +# define setbuf(f,b) +# define setvbuf(w,x,y,z) +# define fopen _wfopen +# define freopen _wfreopen +# define remove(x) DeleteFile(x) +#else +# define DIR_SEPERATOR TEXT("/") +# include +#endif + +/* Include the SDL main definition header */ +#include "SDL.h" +#include "SDL_main.h" + +#ifdef main +# ifndef _WIN32_WCE_EMULATION +# undef main +# endif /* _WIN32_WCE_EMULATION */ +#endif /* main */ + +/* The standard output files */ +#define STDOUT_FILE TEXT("stdout.txt") +#define STDERR_FILE TEXT("stderr.txt") + +/* Set a variable to tell if the stdio redirect has been enabled. */ +static int stdioRedirectEnabled = 0; + +#ifdef _WIN32_WCE + static wchar_t stdoutPath[MAX_PATH]; + static wchar_t stderrPath[MAX_PATH]; +#else + static char stdoutPath[MAX_PATH]; + static char stderrPath[MAX_PATH]; +#endif + +#if defined(_WIN32_WCE) && _WIN32_WCE < 300 +/* seems to be undefined in Win CE although in online help */ +#define isspace(a) (((CHAR)a == ' ') || ((CHAR)a == '\t')) +#endif /* _WIN32_WCE < 300 */ + +static void UnEscapeQuotes( char *arg ) +{ + char *last = NULL; + + while( *arg ) { + if( *arg == '"' && *last == '\\' ) { + char *c_curr = arg; + char *c_last = last; + + while( *c_curr ) { + *c_last = *c_curr; + c_last = c_curr; + c_curr++; + } + *c_last = '\0'; + } + last = arg; + arg++; + } +} + +/* Parse a command line buffer into arguments */ +static int ParseCommandLine(char *cmdline, char **argv) +{ + char *bufp; + char *lastp = NULL; + int argc, last_argc; + + argc = last_argc = 0; + for ( bufp = cmdline; *bufp; ) { + /* Skip leading whitespace */ + while ( isspace(*bufp) ) { + ++bufp; + } + /* Skip over argument */ + if ( *bufp == '"' ) { + ++bufp; + if ( *bufp ) { + if ( argv ) { + argv[argc] = bufp; + } + ++argc; + } + /* Skip over word */ + while ( *bufp && ( *bufp != '"' || (lastp && *lastp == '\\') ) ) { + lastp = bufp; + ++bufp; + } + } else { + if ( *bufp ) { + if ( argv ) { + argv[argc] = bufp; + } + ++argc; + } + /* Skip over word */ + while ( *bufp && ! isspace(*bufp) ) { + ++bufp; + } + } + if ( *bufp ) { + if ( argv ) { + *bufp = '\0'; + } + ++bufp; + } + + /* Strip out \ from \" sequences */ + if( argv && last_argc != argc ) { + UnEscapeQuotes( argv[last_argc] ); + } + last_argc = argc; + } + if ( argv ) { + argv[argc] = NULL; + } + return(argc); +} + +/* Show an error message */ +static void ShowError(const char *title, const char *message) +{ +/* If USE_MESSAGEBOX is defined, you need to link with user32.lib */ +#ifdef USE_MESSAGEBOX + MessageBox(NULL, message, title, MB_ICONEXCLAMATION|MB_OK); +#else + fprintf(stderr, "%s: %s\n", title, message); +#endif +} + +/* Pop up an out of memory message, returns to Windows */ +static BOOL OutOfMemory(void) +{ + ShowError("Fatal Error", "Out of memory - aborting"); + return FALSE; +} + +/* SDL_Quit() shouldn't be used with atexit() directly because + calling conventions may differ... */ +static void cleanup(void) +{ + SDL_Quit(); +} + +/* Remove the output files if there was no output written */ +static void cleanup_output(void) { + FILE *file; + int empty; + + /* Flush the output in case anything is queued */ + fclose(stdout); + fclose(stderr); + + /* Without redirection we're done */ + if (!stdioRedirectEnabled) { + return; + } + + /* See if the files have any output in them */ + if ( stdoutPath[0] ) { + file = fopen(stdoutPath, TEXT("rb")); + if ( file ) { + empty = (fgetc(file) == EOF) ? 1 : 0; + fclose(file); + if ( empty ) { + remove(stdoutPath); + } + } + } + if ( stderrPath[0] ) { + file = fopen(stderrPath, TEXT("rb")); + if ( file ) { + empty = (fgetc(file) == EOF) ? 1 : 0; + fclose(file); + if ( empty ) { + remove(stderrPath); + } + } + } +} + +/* Redirect the output (stdout and stderr) to a file */ +static void redirect_output(void) +{ + DWORD pathlen; +#ifdef _WIN32_WCE + wchar_t path[MAX_PATH]; +#else + char path[MAX_PATH]; +#endif + FILE *newfp; + + pathlen = GetModuleFileName(NULL, path, SDL_arraysize(path)); + while ( pathlen > 0 && path[pathlen] != '\\' ) { + --pathlen; + } + path[pathlen] = '\0'; + +#ifdef _WIN32_WCE + wcsncpy( stdoutPath, path, SDL_arraysize(stdoutPath) ); + wcsncat( stdoutPath, DIR_SEPERATOR STDOUT_FILE, SDL_arraysize(stdoutPath) ); +#else + SDL_strlcpy( stdoutPath, path, SDL_arraysize(stdoutPath) ); + SDL_strlcat( stdoutPath, DIR_SEPERATOR STDOUT_FILE, SDL_arraysize(stdoutPath) ); +#endif + + /* Redirect standard input and standard output */ + newfp = freopen(stdoutPath, TEXT("w"), stdout); + +#ifndef _WIN32_WCE + if ( newfp == NULL ) { /* This happens on NT */ +#if !defined(stdout) + stdout = fopen(stdoutPath, TEXT("w")); +#else + newfp = fopen(stdoutPath, TEXT("w")); + if ( newfp ) { + *stdout = *newfp; + } +#endif + } +#endif /* _WIN32_WCE */ + +#ifdef _WIN32_WCE + wcsncpy( stderrPath, path, SDL_arraysize(stdoutPath) ); + wcsncat( stderrPath, DIR_SEPERATOR STDOUT_FILE, SDL_arraysize(stdoutPath) ); +#else + SDL_strlcpy( stderrPath, path, SDL_arraysize(stderrPath) ); + SDL_strlcat( stderrPath, DIR_SEPERATOR STDERR_FILE, SDL_arraysize(stderrPath) ); +#endif + + newfp = freopen(stderrPath, TEXT("w"), stderr); +#ifndef _WIN32_WCE + if ( newfp == NULL ) { /* This happens on NT */ +#if !defined(stderr) + stderr = fopen(stderrPath, TEXT("w")); +#else + newfp = fopen(stderrPath, TEXT("w")); + if ( newfp ) { + *stderr = *newfp; + } +#endif + } +#endif /* _WIN32_WCE */ + + setvbuf(stdout, NULL, _IOLBF, BUFSIZ); /* Line buffered */ + setbuf(stderr, NULL); /* No buffering */ + stdioRedirectEnabled = 1; +} + +#if defined(_MSC_VER) && !defined(_WIN32_WCE) +/* The VC++ compiler needs main defined */ +#define console_main main +#endif + +/* This is where execution begins [console apps] */ +int console_main(int argc, char *argv[]) +{ + size_t n; + char *bufp, *appname; + int status; + + /* Get the class name from argv[0] */ + appname = argv[0]; + if ( (bufp=SDL_strrchr(argv[0], '\\')) != NULL ) { + appname = bufp+1; + } else + if ( (bufp=SDL_strrchr(argv[0], '/')) != NULL ) { + appname = bufp+1; + } + + if ( (bufp=SDL_strrchr(appname, '.')) == NULL ) + n = SDL_strlen(appname); + else + n = (bufp-appname); + + bufp = SDL_stack_alloc(char, n+1); + if ( bufp == NULL ) { + return OutOfMemory(); + } + SDL_strlcpy(bufp, appname, n+1); + appname = bufp; + + /* Load SDL dynamic link library */ + if ( SDL_Init(SDL_INIT_NOPARACHUTE) < 0 ) { + ShowError("WinMain() error", SDL_GetError()); + return(FALSE); + } + atexit(cleanup_output); + atexit(cleanup); + + /* Sam: + We still need to pass in the application handle so that + DirectInput will initialize properly when SDL_RegisterApp() + is called later in the video initialization. + */ + SDL_SetModuleHandle(GetModuleHandle(NULL)); + + /* Run the application main() code */ + status = SDL_main(argc, argv); + + /* Exit cleanly, calling atexit() functions */ + exit(status); + + /* Hush little compiler, don't you cry... */ + return 0; +} + +/* This is where execution begins [windowed apps] */ +#ifdef _WIN32_WCE +int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPWSTR szCmdLine, int sw) +#else +int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw) +#endif +{ + HMODULE handle; + char **argv; + int argc; + char *cmdline; + char *env_str; +#ifdef _WIN32_WCE + wchar_t *bufp; + int nLen; +#else + char *bufp; + size_t nLen; +#endif + + /* Start up DDHELP.EXE before opening any files, so DDHELP doesn't + keep them open. This is a hack.. hopefully it will be fixed + someday. DDHELP.EXE starts up the first time DDRAW.DLL is loaded. + */ + handle = LoadLibrary(TEXT("DDRAW.DLL")); + if ( handle != NULL ) { + FreeLibrary(handle); + } + + /* Check for stdio redirect settings and do the redirection */ + if ((env_str = SDL_getenv("SDL_STDIO_REDIRECT"))) { + if (SDL_atoi(env_str)) { + redirect_output(); + } + } +#ifndef NO_STDIO_REDIRECT + else { + redirect_output(); + } +#endif + +#ifdef _WIN32_WCE + nLen = wcslen(szCmdLine)+128+1; + bufp = SDL_stack_alloc(wchar_t, nLen*2); + wcscpy (bufp, TEXT("\"")); + GetModuleFileName(NULL, bufp+1, 128-3); + wcscpy (bufp+wcslen(bufp), TEXT("\" ")); + wcsncpy(bufp+wcslen(bufp), szCmdLine,nLen-wcslen(bufp)); + nLen = wcslen(bufp)+1; + cmdline = SDL_stack_alloc(char, nLen); + if ( cmdline == NULL ) { + return OutOfMemory(); + } + WideCharToMultiByte(CP_ACP, 0, bufp, -1, cmdline, nLen, NULL, NULL); +#else + /* Grab the command line */ + bufp = GetCommandLine(); + nLen = SDL_strlen(bufp)+1; + cmdline = SDL_stack_alloc(char, nLen); + if ( cmdline == NULL ) { + return OutOfMemory(); + } + SDL_strlcpy(cmdline, bufp, nLen); +#endif + + /* Parse it into argv and argc */ + argc = ParseCommandLine(cmdline, NULL); + argv = SDL_stack_alloc(char*, argc+1); + if ( argv == NULL ) { + return OutOfMemory(); + } + ParseCommandLine(cmdline, argv); + + /* Run the main program (after a little SDL initialization) */ + console_main(argc, argv); + + /* Hush little compiler, don't you cry... */ + return 0; +} diff --git a/src/SDLmain/win32/version.rc b/src/SDLmain/win32/version.rc new file mode 100644 index 000000000..cf9ba07aa --- /dev/null +++ b/src/SDLmain/win32/version.rc @@ -0,0 +1,38 @@ + +#include "winresrc.h" + +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,2,50,0 + PRODUCTVERSION 1,2,50,0 + FILEFLAGSMASK 0x3fL + FILEFLAGS 0x0L + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", "\0" + VALUE "FileDescription", "SDL\0" + VALUE "FileVersion", "1, 2, 50, 0\0" + VALUE "InternalName", "SDL\0" + VALUE "LegalCopyright", "Copyright © 2021 Sam Lantinga\0" + VALUE "OriginalFilename", "SDL.dll\0" + VALUE "ProductName", "Simple DirectMedia Layer\0" + VALUE "ProductVersion", "1, 2, 50, 0\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END From 6036dc77e50f1ca04264ccd96b9413936b33745f Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Tue, 22 Jun 2021 22:40:50 +0300 Subject: [PATCH 100/606] SDLmain clean-up for windows: - removed src/SDLmain/win32/version.rc: We already have a version.rc, and it's not needed in libSDLmain.a. - fixed mingw linkage (the dreaded `undefined reference to 'WinMain'` issue.) - removed WinCE stuff from and cleaned up SDL_win32_main.c --- CMakeLists.txt | 8 ++- src/SDLmain/win32/SDL_win32_main.c | 96 ++++++------------------------ src/SDLmain/win32/version.rc | 38 ------------ 3 files changed, 23 insertions(+), 119 deletions(-) delete mode 100644 src/SDLmain/win32/version.rc diff --git a/CMakeLists.txt b/CMakeLists.txt index 323849dc2..8f1ea3258 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -109,7 +109,7 @@ endif() if(APPLE) add_library(SDLmain STATIC src/SDLmain/macosx/SDLmain.m) elseif(WIN32) - add_library(SDLmain STATIC src/SDLmain/win32/SDL_win32_main.c src/SDLmain/win32/version.rc) + add_library(SDLmain STATIC src/SDLmain/win32/SDL_win32_main.c) else() add_library(SDLmain STATIC src/SDLmain/dummy/SDL_dummy_main.c) endif() @@ -135,7 +135,11 @@ if(SDL12TESTS) macro(test_program _NAME _SRCS) add_executable(${_NAME} ${_SRCS}) target_include_directories(${_NAME} PRIVATE "include/SDL") - target_link_libraries(${_NAME} SDL SDLmain) + if(MINGW) + target_link_libraries(${_NAME} mingw32 SDLmain SDL) + else() + target_link_libraries(${_NAME} SDLmain SDL) + endif() # Turn off MSVC's aggressive C runtime warnings for the old test programs. if(MSVC) set_target_properties(${_NAME} PROPERTIES COMPILE_DEFINITIONS "${HAVE_OPENGL_DEFINE};_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE") diff --git a/src/SDLmain/win32/SDL_win32_main.c b/src/SDLmain/win32/SDL_win32_main.c index 672b48c12..7775fdafe 100644 --- a/src/SDLmain/win32/SDL_win32_main.c +++ b/src/SDLmain/win32/SDL_win32_main.c @@ -7,52 +7,32 @@ #include #include +#ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN +#endif #include -#ifdef _WIN32_WCE -# define DIR_SEPERATOR TEXT("\\") -# undef _getcwd -# define _getcwd(str,len) wcscpy(str,TEXT("")) -# define setbuf(f,b) -# define setvbuf(w,x,y,z) -# define fopen _wfopen -# define freopen _wfreopen -# define remove(x) DeleteFile(x) -#else -# define DIR_SEPERATOR TEXT("/") -# include -#endif +#define DIR_SEPERATOR "/" /* Include the SDL main definition header */ #include "SDL.h" #include "SDL_main.h" #ifdef main -# ifndef _WIN32_WCE_EMULATION # undef main -# endif /* _WIN32_WCE_EMULATION */ #endif /* main */ /* The standard output files */ -#define STDOUT_FILE TEXT("stdout.txt") -#define STDERR_FILE TEXT("stderr.txt") +#define STDOUT_FILE "stdout.txt" +#define STDERR_FILE "stderr.txt" /* Set a variable to tell if the stdio redirect has been enabled. */ static int stdioRedirectEnabled = 0; -#ifdef _WIN32_WCE - static wchar_t stdoutPath[MAX_PATH]; - static wchar_t stderrPath[MAX_PATH]; -#else - static char stdoutPath[MAX_PATH]; - static char stderrPath[MAX_PATH]; -#endif +static char stdoutPath[MAX_PATH]; +static char stderrPath[MAX_PATH]; -#if defined(_WIN32_WCE) && _WIN32_WCE < 300 -/* seems to be undefined in Win CE although in online help */ #define isspace(a) (((CHAR)a == ' ') || ((CHAR)a == '\t')) -#endif /* _WIN32_WCE < 300 */ static void UnEscapeQuotes( char *arg ) { @@ -174,7 +154,7 @@ static void cleanup_output(void) { /* See if the files have any output in them */ if ( stdoutPath[0] ) { - file = fopen(stdoutPath, TEXT("rb")); + file = fopen(stdoutPath, "rb"); if ( file ) { empty = (fgetc(file) == EOF) ? 1 : 0; fclose(file); @@ -184,7 +164,7 @@ static void cleanup_output(void) { } } if ( stderrPath[0] ) { - file = fopen(stderrPath, TEXT("rb")); + file = fopen(stderrPath, "rb"); if ( file ) { empty = (fgetc(file) == EOF) ? 1 : 0; fclose(file); @@ -199,11 +179,7 @@ static void cleanup_output(void) { static void redirect_output(void) { DWORD pathlen; -#ifdef _WIN32_WCE - wchar_t path[MAX_PATH]; -#else char path[MAX_PATH]; -#endif FILE *newfp; pathlen = GetModuleFileName(NULL, path, SDL_arraysize(path)); @@ -212,58 +188,44 @@ static void redirect_output(void) } path[pathlen] = '\0'; -#ifdef _WIN32_WCE - wcsncpy( stdoutPath, path, SDL_arraysize(stdoutPath) ); - wcsncat( stdoutPath, DIR_SEPERATOR STDOUT_FILE, SDL_arraysize(stdoutPath) ); -#else SDL_strlcpy( stdoutPath, path, SDL_arraysize(stdoutPath) ); SDL_strlcat( stdoutPath, DIR_SEPERATOR STDOUT_FILE, SDL_arraysize(stdoutPath) ); -#endif - + /* Redirect standard input and standard output */ - newfp = freopen(stdoutPath, TEXT("w"), stdout); + newfp = freopen(stdoutPath, "w", stdout); -#ifndef _WIN32_WCE if ( newfp == NULL ) { /* This happens on NT */ #if !defined(stdout) - stdout = fopen(stdoutPath, TEXT("w")); + stdout = fopen(stdoutPath, "w"); #else - newfp = fopen(stdoutPath, TEXT("w")); + newfp = fopen(stdoutPath, "w"); if ( newfp ) { *stdout = *newfp; } #endif } -#endif /* _WIN32_WCE */ -#ifdef _WIN32_WCE - wcsncpy( stderrPath, path, SDL_arraysize(stdoutPath) ); - wcsncat( stderrPath, DIR_SEPERATOR STDOUT_FILE, SDL_arraysize(stdoutPath) ); -#else SDL_strlcpy( stderrPath, path, SDL_arraysize(stderrPath) ); SDL_strlcat( stderrPath, DIR_SEPERATOR STDERR_FILE, SDL_arraysize(stderrPath) ); -#endif - newfp = freopen(stderrPath, TEXT("w"), stderr); -#ifndef _WIN32_WCE + newfp = freopen(stderrPath, "w", stderr); if ( newfp == NULL ) { /* This happens on NT */ #if !defined(stderr) - stderr = fopen(stderrPath, TEXT("w")); + stderr = fopen(stderrPath, "w"); #else - newfp = fopen(stderrPath, TEXT("w")); + newfp = fopen(stderrPath, "w"); if ( newfp ) { *stderr = *newfp; } #endif } -#endif /* _WIN32_WCE */ setvbuf(stdout, NULL, _IOLBF, BUFSIZ); /* Line buffered */ setbuf(stderr, NULL); /* No buffering */ stdioRedirectEnabled = 1; } -#if defined(_MSC_VER) && !defined(_WIN32_WCE) +#if defined(_MSC_VER) /* The VC++ compiler needs main defined */ #define console_main main #endif @@ -322,24 +284,15 @@ int console_main(int argc, char *argv[]) } /* This is where execution begins [windowed apps] */ -#ifdef _WIN32_WCE -int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPWSTR szCmdLine, int sw) -#else int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw) -#endif { HMODULE handle; char **argv; int argc; char *cmdline; char *env_str; -#ifdef _WIN32_WCE - wchar_t *bufp; - int nLen; -#else char *bufp; size_t nLen; -#endif /* Start up DDHELP.EXE before opening any files, so DDHELP doesn't keep them open. This is a hack.. hopefully it will be fixed @@ -362,20 +315,6 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw) } #endif -#ifdef _WIN32_WCE - nLen = wcslen(szCmdLine)+128+1; - bufp = SDL_stack_alloc(wchar_t, nLen*2); - wcscpy (bufp, TEXT("\"")); - GetModuleFileName(NULL, bufp+1, 128-3); - wcscpy (bufp+wcslen(bufp), TEXT("\" ")); - wcsncpy(bufp+wcslen(bufp), szCmdLine,nLen-wcslen(bufp)); - nLen = wcslen(bufp)+1; - cmdline = SDL_stack_alloc(char, nLen); - if ( cmdline == NULL ) { - return OutOfMemory(); - } - WideCharToMultiByte(CP_ACP, 0, bufp, -1, cmdline, nLen, NULL, NULL); -#else /* Grab the command line */ bufp = GetCommandLine(); nLen = SDL_strlen(bufp)+1; @@ -384,7 +323,6 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw) return OutOfMemory(); } SDL_strlcpy(cmdline, bufp, nLen); -#endif /* Parse it into argv and argc */ argc = ParseCommandLine(cmdline, NULL); diff --git a/src/SDLmain/win32/version.rc b/src/SDLmain/win32/version.rc deleted file mode 100644 index cf9ba07aa..000000000 --- a/src/SDLmain/win32/version.rc +++ /dev/null @@ -1,38 +0,0 @@ - -#include "winresrc.h" - -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US - -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,2,50,0 - PRODUCTVERSION 1,2,50,0 - FILEFLAGSMASK 0x3fL - FILEFLAGS 0x0L - FILEOS 0x40004L - FILETYPE 0x2L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904b0" - BEGIN - VALUE "CompanyName", "\0" - VALUE "FileDescription", "SDL\0" - VALUE "FileVersion", "1, 2, 50, 0\0" - VALUE "InternalName", "SDL\0" - VALUE "LegalCopyright", "Copyright © 2021 Sam Lantinga\0" - VALUE "OriginalFilename", "SDL.dll\0" - VALUE "ProductName", "Simple DirectMedia Layer\0" - VALUE "ProductVersion", "1, 2, 50, 0\0" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1200 - END -END From ca068299acc186c1c8871862fad0174d60632def Mon Sep 17 00:00:00 2001 From: David Gow Date: Wed, 23 Jun 2021 16:28:43 +0800 Subject: [PATCH 101/606] Fallback to different-bpp modes more easily A lot of games expect to be able to set the video mode to modes with a variety of pixel formats, but X11 and Wayland do not permit the system pixel format to be changed at runtime. Since SDL is able to convert between these different formats, SDL 1.2 emulated a number of common formats where the system bpp was >= the desired bpp. For sdl12-compat, if no modes are available in the desired bpp: - Expose the mode list from a higher bpp, in the knowledge it can be converted. - Expose 24bpp modes as 32bpp modes if requested, as these are functionally identical. This change mostly updates SDL_ListModes() to fallback to these mode lists when necessary. It also lets SDL_VideoModeOK() find 24bpp modes if a 32bpp mode is expected. With these changes, a number of games which would error out trying to set 16 and 32 bit modes on an X11/Wayland setup which exposes only 24-bit modes now work with all three bit depths. --- src/SDL12_compat.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index f13f26d53..087385a27 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -3471,7 +3471,9 @@ SDL_VideoModeOK(int width, int height, int bpp, Uint32 sdl12flags) if (!vmode->format) { return bpp; } - if (SDL_BITSPERPIXEL(vmode->format) >= (Uint32) bpp) { + if (SDL_BITSPERPIXEL(vmode->format) == 24 && bpp == 32) { + actual_bpp = 32; + } else if (SDL_BITSPERPIXEL(vmode->format) >= (Uint32) bpp) { actual_bpp = SDL_BITSPERPIXEL(vmode->format); } } @@ -3485,6 +3487,7 @@ SDL_VideoModeOK(int width, int height, int bpp, Uint32 sdl12flags) DECLSPEC SDL12_Rect ** SDLCALL SDL_ListModes(const SDL12_PixelFormat *format12, Uint32 flags) { + VideoModeList *best_modes = NULL; Uint32 bpp; int i; @@ -3516,11 +3519,20 @@ SDL_ListModes(const SDL12_PixelFormat *format12, Uint32 flags) VideoModeList *modes = &VideoModes[i]; if (SDL_BITSPERPIXEL(modes->format) == bpp) { return modes->modes12; + } else if (SDL_BITSPERPIXEL(modes->format) == 24 && bpp == 32) { + best_modes = modes; + } else if (SDL_BITSPERPIXEL(modes->format) > bpp) { + if (!best_modes || SDL_BITSPERPIXEL(modes->format) > SDL_BITSPERPIXEL(best_modes->format)) { + best_modes = modes; + } } } - SDL20_SetError("No modes support requested pixel format"); - return NULL; + if (!best_modes) { + SDL20_SetError("No modes support requested pixel format"); + return NULL; + } + return best_modes->modes12; } DECLSPEC void SDLCALL From 0bde9879e87f3c6835e7191ae43357900f3f3641 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Wed, 23 Jun 2021 20:04:50 +0300 Subject: [PATCH 102/606] put back Keysym20to12 in if0'ed out form and added KeysymFromSDL2 macro: In its current state, it is new behavior after PR #97. If #if 0 is flipped to 1, it is the old behavior before PR #97. Helps with testing for now. --- src/SDL12_compat.c | 95 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 93 insertions(+), 2 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 087385a27..bf812fc78 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -2429,6 +2429,96 @@ SDL_GetKeyName(SDL12Key key) return (char *) "unknown key"; } +#if 0 /* https://github.com/libsdl-org/sdl12-compat/pull/97 */ +# define KeysymFromSDL2(_ev20) Keysym20to12((_ev20)->key.keysym.sym) +static SDL12Key +Keysym20to12(const SDL_Keycode keysym20) +{ + if (((int) keysym20) < 127) { /* (most of) low-ASCII maps directly */ + if (keysym20 == SDLK_PAUSE) { + return SDLK12_PAUSE; + } else if (keysym20 == SDLK_CLEAR) { + return SDLK12_CLEAR; + } + return (SDL12Key) keysym20; + } + + switch (keysym20) { + #define CASEKEYSYM20TO12(k20, k12) case SDLK_##k20: return SDLK12_##k12 + CASEKEYSYM20TO12(KP_0, KP0); + CASEKEYSYM20TO12(KP_1, KP1); + CASEKEYSYM20TO12(KP_2, KP2); + CASEKEYSYM20TO12(KP_3, KP3); + CASEKEYSYM20TO12(KP_4, KP4); + CASEKEYSYM20TO12(KP_5, KP5); + CASEKEYSYM20TO12(KP_6, KP6); + CASEKEYSYM20TO12(KP_7, KP7); + CASEKEYSYM20TO12(KP_8, KP8); + CASEKEYSYM20TO12(KP_9, KP9); + CASEKEYSYM20TO12(NUMLOCKCLEAR, NUMLOCK); + CASEKEYSYM20TO12(SCROLLLOCK, SCROLLOCK); + CASEKEYSYM20TO12(RGUI, RMETA); + CASEKEYSYM20TO12(LGUI, LMETA); + CASEKEYSYM20TO12(PRINTSCREEN, PRINT); + #undef CASEKEYSYM20TO12 + + #define CASEKEYSYM20TO12(k) case SDLK_##k: return SDLK12_##k + CASEKEYSYM20TO12(CLEAR); + CASEKEYSYM20TO12(PAUSE); + CASEKEYSYM20TO12(KP_PERIOD); + CASEKEYSYM20TO12(KP_DIVIDE); + CASEKEYSYM20TO12(KP_MULTIPLY); + CASEKEYSYM20TO12(KP_MINUS); + CASEKEYSYM20TO12(KP_PLUS); + CASEKEYSYM20TO12(KP_ENTER); + CASEKEYSYM20TO12(KP_EQUALS); + CASEKEYSYM20TO12(UP); + CASEKEYSYM20TO12(DOWN); + CASEKEYSYM20TO12(RIGHT); + CASEKEYSYM20TO12(LEFT); + CASEKEYSYM20TO12(INSERT); + CASEKEYSYM20TO12(HOME); + CASEKEYSYM20TO12(END); + CASEKEYSYM20TO12(PAGEUP); + CASEKEYSYM20TO12(PAGEDOWN); + CASEKEYSYM20TO12(F1); + CASEKEYSYM20TO12(F2); + CASEKEYSYM20TO12(F3); + CASEKEYSYM20TO12(F4); + CASEKEYSYM20TO12(F5); + CASEKEYSYM20TO12(F6); + CASEKEYSYM20TO12(F7); + CASEKEYSYM20TO12(F8); + CASEKEYSYM20TO12(F9); + CASEKEYSYM20TO12(F10); + CASEKEYSYM20TO12(F11); + CASEKEYSYM20TO12(F12); + CASEKEYSYM20TO12(F13); + CASEKEYSYM20TO12(F14); + CASEKEYSYM20TO12(F15); + CASEKEYSYM20TO12(CAPSLOCK); + CASEKEYSYM20TO12(RSHIFT); + CASEKEYSYM20TO12(LSHIFT); + CASEKEYSYM20TO12(RCTRL); + CASEKEYSYM20TO12(LCTRL); + CASEKEYSYM20TO12(RALT); + CASEKEYSYM20TO12(LALT); + CASEKEYSYM20TO12(MODE); + CASEKEYSYM20TO12(HELP); + CASEKEYSYM20TO12(SYSREQ);; + CASEKEYSYM20TO12(MENU); + CASEKEYSYM20TO12(POWER); + CASEKEYSYM20TO12(UNDO); + #undef CASEKEYSYM20TO12 + default: break; + } + + FIXME("nothing maps to SDLK12_COMPOSE, SDLK12_BREAK, or SDLK12_EURO ...?"); + FIXME("map some of the SDLK12_WORLD keys"); + return SDLK12_UNKNOWN; +} +#else +# define KeysymFromSDL2(_ev20) Scancode20toKeysym12((_ev20)->key.keysym.scancode) static SDL12Key Scancode20toKeysym12(const SDL_Scancode scancode20) { @@ -2573,6 +2663,7 @@ Scancode20toKeysym12(const SDL_Scancode scancode20) FIXME("map some of the SDLK12_WORLD keys"); return SDLK12_UNKNOWN; } +#endif static Uint8 Scancode20to12(SDL_Scancode sc) @@ -2837,7 +2928,7 @@ EventFilter20to12(void *data, SDL_Event *event20) if (event20->key.repeat) { return 1; /* ignore 2.0-style key repeat events */ } - event12.key.keysym.sym = Scancode20toKeysym12(event20->key.keysym.scancode); + event12.key.keysym.sym = KeysymFromSDL2(event20); KeyState[event12.key.keysym.sym] = event20->key.state; @@ -2859,7 +2950,7 @@ EventFilter20to12(void *data, SDL_Event *event20) return 1; /* ignore 2.0-style key repeat events */ } - PendingKeydownEvent.key.keysym.sym = Scancode20toKeysym12(event20->key.keysym.scancode); + PendingKeydownEvent.key.keysym.sym = KeysymFromSDL2(event20); KeyState[PendingKeydownEvent.key.keysym.sym] = event20->key.state; From b5715546c0a995d69cbdaffe663adbeb9a2228c2 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 24 Jun 2021 15:24:07 -0400 Subject: [PATCH 103/606] Implemented SDL_syswm API. --- include/SDL/SDL_config.h | 9 ++- include/SDL/SDL_syswm.h | 9 +-- src/SDL12_compat.c | 166 +++++++++++++++++++++++++++++++++++---- src/SDL20_syms.h | 3 + test/testwm.c | 46 +++++++++++ 5 files changed, 208 insertions(+), 25 deletions(-) diff --git a/include/SDL/SDL_config.h b/include/SDL/SDL_config.h index 6ab8c8799..dac480d5d 100644 --- a/include/SDL/SDL_config.h +++ b/include/SDL/SDL_config.h @@ -163,6 +163,13 @@ stage, though. Send patches if your platform lacks something. */ #define HAVE_SETJMP 1 #endif -/* Don't define any of the SDL backend, under the assumption checking for these against the headers won't work anyhow. */ +/* Don't define most of the SDL backends, under the assumption checking for these against the headers won't work anyhow. + The exception is the X11 backend; you need its define to know if you can use its syswm interface. */ + +# if defined(__unix__) && !defined(__APPLE__) && defined(__has_include) +# if __has_include() +# define SDL_VIDEO_DRIVER_X11 1 +# endif +# endif #endif /* _SDL_config_h */ diff --git a/include/SDL/SDL_syswm.h b/include/SDL/SDL_syswm.h index b6b0c9e5b..65666dac2 100644 --- a/include/SDL/SDL_syswm.h +++ b/include/SDL/SDL_syswm.h @@ -32,14 +32,7 @@ real SDL-1.2 available to you. */ #ifndef SDL_PROTOTYPES_ONLY -# if defined(__unix__) && !defined(__APPLE__) && defined(__has_include) -# if __has_include() -# define SDL12_COMPAT_SUPPORT_SYSWM_X11 1 -# endif -# endif - -# if defined(SDL12_COMPAT_SUPPORT_SYSWM_X11) -# undef SDL12_COMPAT_SUPPORT_SYSWM_X11 +# if defined(SDL_VIDEO_DRIVER_X11) # include # include diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index bf812fc78..a849b83d7 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -36,7 +36,13 @@ #include #include -#ifndef _WIN32 + +#ifdef _WIN32 +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN 1 +#endif +#include +#else #include /* fprintf(), etc. */ #include /* for abort() */ #include @@ -566,6 +572,54 @@ typedef struct SDL12_keysym #define SDL12_RELEASED 0 #define SDL12_PRESSED 1 +#if defined(SDL_VIDEO_DRIVER_X11) /* SDL_VIDEO_DRIVER_X11 refers to the SDL2 headers. */ +typedef enum SDL_SYSWM_TYPE /* this is only used for 1.2 X11 syswm */ +{ + SDL12_SYSWM_X11 +} SDL12_SYSWM_TYPE; +#endif + +typedef struct SDL12_SysWMmsg +{ + SDL_version version; +#if defined(_WIN32) + HWND hwnd; + UINT msg; + WPARAM wParam; + LPARAM lParam; +#elif defined(SDL_VIDEO_DRIVER_X11) + SDL12_SYSWM_TYPE subsystem; + union { XEvent xevent; } event; +#else + int data; /* unused at the moment. */ +#endif +} SDL12_SysWMmsg; + +typedef struct SDL12_SysWMinfo +{ + SDL_version version; +#if defined(_WIN32) + HWND window; + HGLRC hglrc; +#elif defined(SDL_VIDEO_DRIVER_X11) + SDL12_SYSWM_TYPE subsystem; + union { + struct { + Display *display; + Window window; + void (*lock_func)(void); + void (*unlock_func)(void); + Window fswindow; + Window wmwindow; + Display *gfxdisplay; + } x11; + } info; +#else + int data; /* unused at the moment. */ +#endif +} SDL12_SysWMinfo; + + typedef enum { SDL12_NOEVENT = 0, @@ -690,7 +744,7 @@ typedef struct typedef struct { Uint8 type; - void *msg; + SDL12_SysWMmsg *msg; } SDL12_SysWMEvent; typedef union @@ -863,6 +917,7 @@ static char *WindowIconTitle = NULL; static SDL_Surface *VideoIcon20 = NULL; static int EnabledUnicode = 0; static int VideoDisplayIndex = 0; +static SDL_bool SupportSysWM = SDL_FALSE; static SDL_bool CDRomInit = SDL_FALSE; static char *CDRomPath = NULL; static SDL12_CD *CDRomDevice = NULL; @@ -889,11 +944,11 @@ static GLuint OpenGLLogicalScalingMultisampleDepth = 0; static GLuint OpenGLCurrentReadFBO = 0; static GLuint OpenGLCurrentDrawFBO = 0; - /* !!! FIXME: need a mutex for the event queue. */ #define SDL12_MAXEVENTS 128 typedef struct EventQueueType { + SDL12_SysWMmsg syswm_msg; /* save space for a copy of this in case we use it. */ SDL12_Event event12; struct EventQueueType *next; } EventQueueType; @@ -909,10 +964,6 @@ static SDL12_Event PendingKeydownEvent; /* Obviously we can't use SDL_LoadObject() to load SDL2. :) */ static char loaderror[256]; #if defined(_WIN32) - #ifndef WIN32_LEAN_AND_MEAN - #define WIN32_LEAN_AND_MEAN 1 - #endif - #include #define DIRSEP "\\" #define SDL20_LIBNAME "SDL2.dll" /* require SDL2 >= 2.0.12 for SDL_CreateThread binary compatibility */ @@ -1021,7 +1072,6 @@ static char loaderror[256]; #define DIRSEP "/" #endif - static void * LoadSDL20Symbol(const char *fn, int *okay) { @@ -1193,6 +1243,7 @@ SDL_UnregisterApp(void) } #endif + DECLSPEC const SDL_version * SDLCALL SDL_Linked_Version(void) { @@ -1671,7 +1722,17 @@ Init12Video(void) SDL20_memset(&PendingKeydownEvent, 0, sizeof(SDL12_Event)); SDL20_memset(EventStates, SDL_ENABLE, sizeof (EventStates)); /* on by default */ + EventStates[SDL12_SYSWMEVENT] = SDL_IGNORE; /* off by default. */ + SDL20_EventState(SDL_SYSWMEVENT, SDL_IGNORE); + +#if defined(SDL_VIDEO_DRIVER_WINDOWS) + SupportSysWM = (SDL20_strcmp(driver, "windows") == 0) ? SDL_TRUE : SDL_FALSE; +#elif defined(SDL_VIDEO_DRIVER_X11) + SupportSysWM = (SDL20_strcmp(driver, "x11") == 0) ? SDL_TRUE : SDL_FALSE; +#else + SupportSysWM = SDL_FALSE; +#endif SDL20_AddEventWatch(EventFilter20to12, NULL); @@ -1975,6 +2036,11 @@ SDL_PushEvent(SDL12_Event *event12) SDL20_memcpy(&item->event12, event12, sizeof (SDL12_Event)); + if (event12->type == SDL12_SYSWMEVENT) { /* make a copy of the data here */ + SDL20_memcpy(&item->syswm_msg, event12->syswm.msg, sizeof (SDL12_SysWMmsg)); + item->event12.syswm.msg = &item->syswm_msg; + } + return 0; } @@ -2074,6 +2140,9 @@ SDL_EventState(Uint8 type, int state) if (state != SDL_QUERY) { EventStates[type] = state; + if ((type == SDL12_SYSWMEVENT) && SupportSysWM) { /* we only enable syswm in SDL2 if it makes sense. */ + SDL20_EventState(SDL_SYSWMEVENT, state); + } } if (state == SDL_IGNORE) { /* drop existing events of this type. */ while (SDL_PeepEvents(&e, 1, SDL_GETEVENT, (1<syswm.msg->subsystem == SDL_SYSWM_WINDOWS); + msg.hwnd = event20->syswm.msg->hwnd; + msg.msg = event20->syswm.msg->msg; + msg.wParam = event20->syswm.msg->wParam; + msg.lParam = event20->syswm.msg->lParam; + #elif defined(SDL_VIDEO_DRIVER_X11) + SDL_assert(event20->syswm.msg->subsystem == SDL_SYSWM_X11); + msg.subsystem = SDL12_SYSWM_X11; + SDL20_memcpy(&msg.event.xevent, &event20->syswm.msg->msg.x11.event, sizeof (XEvent)); + #else + SDL_assert(!"should have been caught by !SupportsSysWM test"); + #endif + + SDL20_memcpy(&msg.version, SDL_Linked_Version(), sizeof (msg.version)); + event12.type = SDL12_SYSWMEVENT; + event12.syswm.msg = &msg; /* this is stack-allocated, but we copy and update the pointer later. */ + break; case SDL_KEYUP: if (event20->key.repeat) { @@ -5243,14 +5334,57 @@ SDL_SetColors(SDL12_Surface *surface12, const SDL_Color * colors, int firstcolor return SDL_SetPalette(surface12, SDL12_LOGPAL | SDL12_PHYSPAL, colors, firstcolor, ncolors); } + +#if defined(SDL_VIDEO_DRIVER_X11) +/* In 1.2, these would lock the event thread (if you _used_ the event thread), and call XSync(SDL_Display, False) before unlocking */ +static void x11_lock_display(void) {} +static void x11_unlock_display(void) {} +#endif + DECLSPEC int SDLCALL -SDL_GetWMInfo(SDL_SysWMinfo * info) +SDL_GetWMInfo(SDL12_SysWMinfo *info12) { - /*return SDL20_GetWindowWMInfo(VideoWindow20, info);*/ - FIXME("write me"); - (void)info; - SDL20_Unsupported(); - return 0; /* some programs only test against 0, not -1 */ + SDL_SysWMinfo info20; + + if (info12->version.major > 1) { + SDL20_SetError("Requested version is unsupported"); + return 0; /* some programs only test against 0, not -1 */ + } else if (!SupportSysWM) { + SDL20_SetError("No SysWM support available"); + return 0; /* some programs only test against 0, not -1 */ + } + + SDL_zero(info20); + SDL_VERSION(&info20.version); + if (!SDL20_GetWindowWMInfo(VideoWindow20, &info20)) { + return 0; /* some programs only test against 0, not -1 */ + } + +#if defined(SDL_VIDEO_DRIVER_WINDOWS) + SDL_assert(info20.subsystem == SDL_SYSWM_WINDOWS); + info12->window = info20.win.window; + if (SDL_VERSIONNUM(info12->version.major, info12->version.minor, info12->version.patch) >= SDL_VERSIONNUM(1, 2, 5)) { + info12->hglrc = (HGLRC) VideoGLContext20; + } +#elif defined(SDL_VIDEO_DRIVER_X11) + SDL_assert(info20.subsystem == SDL_SYSWM_X11); + info12->subsystem = SDL12_SYSWM_X11; + info12->info.x11.display = info20.info.x11.display; + info12->info.x11.window = info20.info.x11.window; + if (SDL_VERSIONNUM(info12->version.major, info12->version.minor, info12->version.patch) >= SDL_VERSIONNUM(1, 0, 2)) { + info12->info.x11.fswindow = 0; /* these don't exist in SDL2. */ + info12->info.x11.wmwindow = 0; + } + if (SDL_VERSIONNUM(info12->version.major, info12->version.minor, info12->version.patch) >= SDL_VERSIONNUM(1, 2, 12)) { + info12->info.x11.gfxdisplay = info20.info.x11.display; /* shrug */ + } + info12->info.x11.lock_func = x11_lock_display; /* just no-ops for now */ + info12->info.x11.unlock_func = x11_unlock_display; +#else + info12->data = 0; /* shrug */ +#endif + + return 1; } DECLSPEC SDL12_Overlay * SDLCALL diff --git a/src/SDL20_syms.h b/src/SDL20_syms.h index 0937d8ac7..36ca62487 100644 --- a/src/SDL20_syms.h +++ b/src/SDL20_syms.h @@ -70,6 +70,9 @@ SDL20_SYM(void,PumpEvents,(void),(),) SDL20_SYM(void,SetEventFilter,(SDL_EventFilter a, void *b),(a,b),) SDL20_SYM(void,AddEventWatch,(SDL_EventFilter a, void *b),(a,b),) SDL20_SYM(void,DelEventWatch,(SDL_EventFilter a, void *b),(a,b),) +SDL20_SYM(Uint8,EventState,(Uint32 a, int b),(a,b),return) + +SDL20_SYM(SDL_bool,GetWindowWMInfo,(SDL_Window *a, SDL_SysWMinfo *b),(a,b),) SDL20_SYM(int,GetNumDisplayModes,(int a),(a),return) SDL20_SYM(int,GetDisplayMode,(int a, int b, SDL_DisplayMode *c),(a,b,c),return) diff --git a/test/testwm.c b/test/testwm.c index 9c3c0506b..00d53d1ee 100644 --- a/test/testwm.c +++ b/test/testwm.c @@ -5,8 +5,14 @@ #include #include +#define TEST_SYSWM 0 + #include "SDL.h" +#ifdef TEST_SYSWM +#include "SDL_syswm.h" +#endif + /* Is the cursor visible? */ static int visible = 1; @@ -318,6 +324,18 @@ int SDLCALL FilterEvents(const SDL_Event *event) printf("Quit demanded\n"); return(1); + case SDL_SYSWMEVENT: + #ifdef TEST_SYSWM + #ifdef _WIN32 + printf("Windows syswm event: hwnd=%X msg=%X wparam=%X lparam=%X\n", (unsigned int) (size_t) event->syswm.msg->hwnd, (unsigned int) (size_t) event->syswm.msg->msg, (unsigned int) (size_t) event->syswm.msg->wparam, (unsigned int) (size_t) event->syswm.msg->lparam); + #elif defined(SDL_VIDEO_DRIVER_X11) + printf("X11 syswm event: %d\n", event->syswm.msg->event.xevent.type); + #else + printf("Generic syswm event: data=%d\n", event->syswm.msg->data); + #endif + #endif + return(1); + /* This will never happen because events queued directly to the event queue are not filtered. */ @@ -413,6 +431,34 @@ int main(int argc, char *argv[]) quit(1); } +#ifdef TEST_SYSWM + { + SDL_SysWMinfo syswm_info; + SDL_VERSION(&syswm_info.version); + if (SDL_GetWMInfo(&syswm_info) != 1) { + printf("Failed to get syswm info: %s\n", SDL_GetError()); + } else { + #ifdef _WIN32 + printf("Windows syswm info: hwnd=%X hglrc=%X\n", + (unsigned int) (size_t) syswm_info.hwnd, + (unsigned int) (size_t) syswm_info.hglrc); + #elif defined(SDL_VIDEO_DRIVER_X11) + printf("X11 syswm info: display=%p window=%X lock_func=%p unlock_func=%p fswindow=%X wmwindow=%X gfxdisplay=%p\n", + syswm_info.info.x11.display, + (unsigned int) (size_t) syswm_info.info.x11.window, + syswm_info.info.x11.lock_func, + syswm_info.info.x11.unlock_func, + (unsigned int) (size_t) syswm_info.info.x11.fswindow, + (unsigned int) (size_t) syswm_info.info.x11.wmwindow, + syswm_info.info.x11.gfxdisplay); + #else + printf("Generic syswm info: data=%X hglrc=%X\n", syswm_info.data); + #endif + } + } + SDL_EventState(SDL_SYSWMEVENT, SDL_ENABLE); +#endif + /* Set an event filter that discards everything but QUIT */ SDL_SetEventFilter(FilterEvents); From 61e2b12b18a542ef613fbf51f211453cd9042281 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 24 Jun 2021 15:26:43 -0400 Subject: [PATCH 104/606] Added a FIXME --- src/SDL12_compat.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index a849b83d7..8d25fb74c 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1765,6 +1765,7 @@ DECLSPEC int SDLCALL SDL_VideoInit(const char *driver, Uint32 flags) { (void) flags; + FIXME("Does this need to call Init12Video?"); return SDL20_VideoInit(driver); } From ceee6cd0643aa58a867b8639df6ed0c2255dde6e Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 24 Jun 2021 15:26:53 -0400 Subject: [PATCH 105/606] Fixed a call to SDL_SetError that should be SDL20_SetError --- src/SDL12_compat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 8d25fb74c..753cddffc 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -6428,7 +6428,7 @@ ValidCDDriveIndex(const int drive) } if (!CDRomPath || (drive != 0)) { - SDL_SetError("Invalid CD-ROM drive index"); + SDL20_SetError("Invalid CD-ROM drive index"); return SDL_FALSE; } From b9645146f275ffa3c3a04393e06cdd41133ffa5c Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 24 Jun 2021 15:35:12 -0400 Subject: [PATCH 106/606] Patched to compile on Windows. --- src/SDL12_compat.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 753cddffc..7a4ed8b85 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -2999,10 +2999,10 @@ EventFilter20to12(void *data, SDL_Event *event20) #if defined(SDL_VIDEO_DRIVER_WINDOWS) SDL_assert(event20->syswm.msg->subsystem == SDL_SYSWM_WINDOWS); - msg.hwnd = event20->syswm.msg->hwnd; - msg.msg = event20->syswm.msg->msg; - msg.wParam = event20->syswm.msg->wParam; - msg.lParam = event20->syswm.msg->lParam; + msg.hwnd = event20->syswm.msg->win.hwnd; + msg.msg = event20->syswm.msg->win.msg; + msg.wParam = event20->syswm.msg->win.wParam; + msg.lParam = event20->syswm.msg->win.lParam; #elif defined(SDL_VIDEO_DRIVER_X11) SDL_assert(event20->syswm.msg->subsystem == SDL_SYSWM_X11); msg.subsystem = SDL12_SYSWM_X11; From 55f7a83149412e5cb524c84310120ebb18acad0f Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 24 Jun 2021 15:37:09 -0400 Subject: [PATCH 107/606] Patched to build on Windows, attempt 2. --- src/SDL12_compat.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 7a4ed8b85..1daf2473e 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -2999,10 +2999,10 @@ EventFilter20to12(void *data, SDL_Event *event20) #if defined(SDL_VIDEO_DRIVER_WINDOWS) SDL_assert(event20->syswm.msg->subsystem == SDL_SYSWM_WINDOWS); - msg.hwnd = event20->syswm.msg->win.hwnd; - msg.msg = event20->syswm.msg->win.msg; - msg.wParam = event20->syswm.msg->win.wParam; - msg.lParam = event20->syswm.msg->win.lParam; + msg.hwnd = event20->syswm.msg->msg.win.hwnd; + msg.msg = event20->syswm.msg->msg.win.msg; + msg.wParam = event20->syswm.msg->msg.win.wParam; + msg.lParam = event20->syswm.msg->msg.win.lParam; #elif defined(SDL_VIDEO_DRIVER_X11) SDL_assert(event20->syswm.msg->subsystem == SDL_SYSWM_X11); msg.subsystem = SDL12_SYSWM_X11; From eef51b76f19424b29749123288883e1a38fec74b Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 24 Jun 2021 15:40:22 -0400 Subject: [PATCH 108/606] Patched to compile on Window, attempt 3. :/ --- src/SDL12_compat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 1daf2473e..f3e949903 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -5363,7 +5363,7 @@ SDL_GetWMInfo(SDL12_SysWMinfo *info12) #if defined(SDL_VIDEO_DRIVER_WINDOWS) SDL_assert(info20.subsystem == SDL_SYSWM_WINDOWS); - info12->window = info20.win.window; + info12->window = info20.info.win.window; if (SDL_VERSIONNUM(info12->version.major, info12->version.minor, info12->version.patch) >= SDL_VERSIONNUM(1, 2, 5)) { info12->hglrc = (HGLRC) VideoGLContext20; } From b1c825d2b452307db593c9ff97ea5c93a549ebea Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 24 Jun 2021 15:42:35 -0400 Subject: [PATCH 109/606] Turn of Visual C's silly C runtime warnings in SDLmain. --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8f1ea3258..14c252a1c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -110,6 +110,7 @@ if(APPLE) add_library(SDLmain STATIC src/SDLmain/macosx/SDLmain.m) elseif(WIN32) add_library(SDLmain STATIC src/SDLmain/win32/SDL_win32_main.c) + set_target_properties(SDLmain PROPERTIES COMPILE_DEFINITIONS "$_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE") # !!! FIXME: don't use C runtime? We fixed this in SDL2. else() add_library(SDLmain STATIC src/SDLmain/dummy/SDL_dummy_main.c) endif() From 326d950c761fae2f5d26907bed735b8de940e524 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 24 Jun 2021 15:48:48 -0400 Subject: [PATCH 110/606] Patched to compile with Windows, attempt 341234. --- test/testwm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/testwm.c b/test/testwm.c index 00d53d1ee..7647d6980 100644 --- a/test/testwm.c +++ b/test/testwm.c @@ -327,7 +327,7 @@ int SDLCALL FilterEvents(const SDL_Event *event) case SDL_SYSWMEVENT: #ifdef TEST_SYSWM #ifdef _WIN32 - printf("Windows syswm event: hwnd=%X msg=%X wparam=%X lparam=%X\n", (unsigned int) (size_t) event->syswm.msg->hwnd, (unsigned int) (size_t) event->syswm.msg->msg, (unsigned int) (size_t) event->syswm.msg->wparam, (unsigned int) (size_t) event->syswm.msg->lparam); + printf("Windows syswm event: hwnd=%X msg=%X wparam=%X lparam=%X\n", (unsigned int) (size_t) event->syswm.msg->hwnd, (unsigned int) (size_t) event->syswm.msg->msg, (unsigned int) (size_t) event->syswm.msg->wParam, (unsigned int) (size_t) event->syswm.msg->lParam); #elif defined(SDL_VIDEO_DRIVER_X11) printf("X11 syswm event: %d\n", event->syswm.msg->event.xevent.type); #else @@ -440,7 +440,7 @@ int main(int argc, char *argv[]) } else { #ifdef _WIN32 printf("Windows syswm info: hwnd=%X hglrc=%X\n", - (unsigned int) (size_t) syswm_info.hwnd, + (unsigned int) (size_t) syswm_info.window, (unsigned int) (size_t) syswm_info.hglrc); #elif defined(SDL_VIDEO_DRIVER_X11) printf("X11 syswm info: display=%p window=%X lock_func=%p unlock_func=%p fswindow=%X wmwindow=%X gfxdisplay=%p\n", From 08b5def22f66d4baa04bcca382fd5e8df5fcb7e1 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 24 Jun 2021 15:49:01 -0400 Subject: [PATCH 111/606] Check for win32 define before x11, in case the win32 machine has X11 support. --- include/SDL/SDL_syswm.h | 52 ++++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/include/SDL/SDL_syswm.h b/include/SDL/SDL_syswm.h index 65666dac2..187b34e3a 100644 --- a/include/SDL/SDL_syswm.h +++ b/include/SDL/SDL_syswm.h @@ -32,7 +32,32 @@ real SDL-1.2 available to you. */ #ifndef SDL_PROTOTYPES_ONLY -# if defined(SDL_VIDEO_DRIVER_X11) +# if defined(__WIN32__) +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +# endif +# include + +# include "begin_code.h" + + typedef struct SDL_SysWMmsg + { + SDL_version version; + HWND hwnd; + UINT msg; + WPARAM wParam; + LPARAM lParam; + } SDL_SysWMmsg; + + typedef struct SDL_SysWMinfo { + SDL_version version; + HWND window; + HGLRC hglrc; + } SDL_SysWMinfo; + +# include "close_code.h" + +# elif defined(SDL_VIDEO_DRIVER_X11) # include # include @@ -71,31 +96,6 @@ real SDL-1.2 available to you. */ # include "close_code.h" -# elif defined(__WIN32__) -# ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN -# endif -# include - -# include "begin_code.h" - - typedef struct SDL_SysWMmsg - { - SDL_version version; - HWND hwnd; - UINT msg; - WPARAM wParam; - LPARAM lParam; - } SDL_SysWMmsg; - - typedef struct SDL_SysWMinfo { - SDL_version version; - HWND window; - HGLRC hglrc; - } SDL_SysWMinfo; - -# include "close_code.h" - # else # include "begin_code.h" From 271273c6ee03ae8c32f98827abbc530fc08af9ae Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Mon, 28 Jun 2021 15:55:40 +0300 Subject: [PATCH 112/606] Fixed typo in cmake script for win32 SDLmain compile definitions. Fixes: https://github.com/libsdl-org/sdl12-compat/issues/117 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 14c252a1c..ed4ba0156 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -110,7 +110,7 @@ if(APPLE) add_library(SDLmain STATIC src/SDLmain/macosx/SDLmain.m) elseif(WIN32) add_library(SDLmain STATIC src/SDLmain/win32/SDL_win32_main.c) - set_target_properties(SDLmain PROPERTIES COMPILE_DEFINITIONS "$_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE") # !!! FIXME: don't use C runtime? We fixed this in SDL2. + set_target_properties(SDLmain PROPERTIES COMPILE_DEFINITIONS "_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE") # !!! FIXME: don't use C runtime? We fixed this in SDL2. else() add_library(SDLmain STATIC src/SDLmain/dummy/SDL_dummy_main.c) endif() From 547c1b58c3a6210c2a7e5eeb84decf98d7723f24 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Mon, 28 Jun 2021 15:55:56 +0300 Subject: [PATCH 113/606] include/SDL/SDL_events.h: fixed SDL_SysWMmsg redifinition error. --- include/SDL/SDL_events.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/SDL/SDL_events.h b/include/SDL/SDL_events.h index f48eb8386..763d6a2e1 100644 --- a/include/SDL/SDL_events.h +++ b/include/SDL/SDL_events.h @@ -185,11 +185,11 @@ typedef struct SDL_UserEvent void *data2; } SDL_UserEvent; -typedef struct SDL_SysWMmsg SDL_SysWMmsg; +struct SDL_SysWMmsg; typedef struct SDL_SysWMEvent { Uint8 type; - SDL_SysWMmsg *msg; + struct SDL_SysWMmsg *msg; } SDL_SysWMEvent; typedef union SDL_Event From cf47f88e169cc9680e2dd1a89f775e2da129cded Mon Sep 17 00:00:00 2001 From: David Gow Date: Mon, 28 Jun 2021 14:02:19 +0800 Subject: [PATCH 114/606] Mouse position should be consistant in relative mode When the mouse is in Relative Mode (MouseInputIsRelative is true), we "fake" the mouse position by integrating the relative coordinates (adding them to the MousePosition variable, which accumulates the position over time). However, only SDL_GetMouseState() would actually use these coordinates, events still used the raw position from the system (possibly scaled, as both the SDL_RenderSetLogicalSize() and OpenGL based scaling only affects the position, not the relative values). This creates a mismatch: mouse coordinates received from events don't match those received from SDL_GetMouseState(). Instead, we should update the mouse coordinates of the SDL 1.2 events produced to match what we're keeing in the MousePosition variable. We also do this for mouse button events, as otherwise clicks would hit a different target from the visible cursor if a software cursor is rendered. This is still not perfect: the real and fake mouse positions are different, so toggling relative mode can result in a "jump" in the mouse coordinates. Relative mouse movements are also not scaled, so the mouse movement speed can be different in relative mode. Tested this against Ren'py SDL 1.2's software mouse cursor option, and verified no regressions in Wolf4SDL and Multiwinia. --- src/SDL12_compat.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index f3e949903..67fb13326 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -3138,6 +3138,7 @@ EventFilter20to12(void *data, SDL_Event *event20) } else if (MousePosition.axis >= VideoSurface12->dim) { \ MousePosition.axis = (VideoSurface12->dim - 1); \ } \ + event12.motion.axis = MousePosition.axis; \ } ADJUST_RELATIVE(x, xrel, w); ADJUST_RELATIVE(y, yrel, h); @@ -3156,9 +3157,15 @@ EventFilter20to12(void *data, SDL_Event *event20) event12.button.button += 2; /* SDL_BUTTON_X1/2 */ } event12.button.state = event20->button.state; - AdjustOpenGLLogicalScalingPoint(&event20->button.x, &event20->button.y); - event12.button.x = (Uint16) event20->button.x; - event12.button.y = (Uint16) event20->button.y; + if (MouseInputIsRelative) { + /* If we're using relative mouse input, we need to use our "fake" position. */ + event12.button.x = MousePosition.x; + event12.button.y = MousePosition.y; + } else { + AdjustOpenGLLogicalScalingPoint(&event20->button.x, &event20->button.y); + event12.button.x = (Uint16) event20->button.x; + event12.button.y = (Uint16) event20->button.y; + } break; case SDL_MOUSEBUTTONUP: @@ -3169,9 +3176,15 @@ EventFilter20to12(void *data, SDL_Event *event20) event12.button.button += 2; /* SDL_BUTTON_X1/2 */ } event12.button.state = event20->button.state; - AdjustOpenGLLogicalScalingPoint(&event20->button.x, &event20->button.y); - event12.button.x = (Uint16) event20->button.x; - event12.button.y = (Uint16) event20->button.y; + if (MouseInputIsRelative) { + /* If we're using relative mouse input, we need to use our "fake" position. */ + event12.button.x = MousePosition.x; + event12.button.y = MousePosition.y; + } else { + AdjustOpenGLLogicalScalingPoint(&event20->button.x, &event20->button.y); + event12.button.x = (Uint16) event20->button.x; + event12.button.y = (Uint16) event20->button.y; + } break; case SDL_MOUSEWHEEL: From 6baacbea518d85296e95b307bf6312667a9bfb25 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Fri, 9 Jul 2021 10:33:50 +0300 Subject: [PATCH 115/606] testwm.c: fixed format string for 'Generic syswm info' case. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit testwm.c: In function ‘main’: testwm.c:455: warning: too few arguments for format --- test/testwm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/testwm.c b/test/testwm.c index 7647d6980..aef4e6002 100644 --- a/test/testwm.c +++ b/test/testwm.c @@ -452,7 +452,7 @@ int main(int argc, char *argv[]) (unsigned int) (size_t) syswm_info.info.x11.wmwindow, syswm_info.info.x11.gfxdisplay); #else - printf("Generic syswm info: data=%X hglrc=%X\n", syswm_info.data); + printf("Generic syswm info: data=%X\n", syswm_info.data); #endif } } From 6ad7a7e7498cf1d7f49b62a1a2c88abfc195575b Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Fri, 9 Jul 2021 10:50:02 +0300 Subject: [PATCH 116/606] do typedef SDL_SysWMmsg in SDL_events.h, adjust SDL_syswm.h accordingly. Fixes: https://github.com/libsdl-org/sdl12-compat/issues/118 --- include/SDL/SDL_events.h | 1 + include/SDL/SDL_syswm.h | 12 ++++++------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/include/SDL/SDL_events.h b/include/SDL/SDL_events.h index 763d6a2e1..4154b3e63 100644 --- a/include/SDL/SDL_events.h +++ b/include/SDL/SDL_events.h @@ -186,6 +186,7 @@ typedef struct SDL_UserEvent } SDL_UserEvent; struct SDL_SysWMmsg; +typedef struct SDL_SysWMmsg SDL_SysWMmsg; typedef struct SDL_SysWMEvent { Uint8 type; diff --git a/include/SDL/SDL_syswm.h b/include/SDL/SDL_syswm.h index 187b34e3a..007618d10 100644 --- a/include/SDL/SDL_syswm.h +++ b/include/SDL/SDL_syswm.h @@ -40,14 +40,14 @@ real SDL-1.2 available to you. */ # include "begin_code.h" - typedef struct SDL_SysWMmsg + struct SDL_SysWMmsg { SDL_version version; HWND hwnd; UINT msg; WPARAM wParam; LPARAM lParam; - } SDL_SysWMmsg; + }; typedef struct SDL_SysWMinfo { SDL_version version; @@ -68,14 +68,14 @@ real SDL-1.2 available to you. */ SDL_SYSWM_X11 } SDL_SYSWM_TYPE; - typedef struct SDL_SysWMmsg + struct SDL_SysWMmsg { SDL_version version; SDL_SYSWM_TYPE subsystem; union { XEvent xevent; } event; - } SDL_SysWMmsg; + }; typedef struct SDL_SysWMinfo { @@ -100,11 +100,11 @@ real SDL-1.2 available to you. */ # include "begin_code.h" - typedef struct SDL_SysWMmsg + struct SDL_SysWMmsg { SDL_version version; int data; - } SDL_SysWMmsg; + }; typedef struct SDL_SysWMinfo { From 3f60129991da584f45340f6727966223d5faecbe Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Fri, 9 Jul 2021 11:55:10 +0300 Subject: [PATCH 117/606] cmake: check declaration-after-statement flags before using. --- CMakeLists.txt | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ed4ba0156..7dc89f513 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,14 +39,26 @@ set(SDL12COMPAT_SRCS add_library(SDL SHARED ${SDL12COMPAT_SRCS}) include(CheckCSourceCompiles) +include(CheckCCompilerFlag) include(GNUInstallDirs) include("cmake/modules/FindSDL2.cmake") target_include_directories(SDL PRIVATE ${SDL2_INCLUDE_DIRS}) +set(EXTRA_CFLAGS ) if (CMAKE_C_COMPILER_ID MATCHES "Clang|GNU") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Werror=declaration-after-statement") # force these universally. + set(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wall") + check_c_compiler_flag(-Wdeclaration-after-statement HAVE_WDECLARATION_AFTER_STATEMENT) + if(HAVE_WDECLARATION_AFTER_STATEMENT) + set(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wdeclaration-after-statement") + endif() + check_c_compiler_flag(-Werror=declaration-after-statement HAVE_WERROR_DECLARATION_AFTER_STATEMENT) + if(HAVE_WERROR_DECLARATION_AFTER_STATEMENT) + set(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Werror=declaration-after-statement") + endif() endif() +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") +string(STRIP "${CMAKE_C_FLAGS}" CMAKE_C_FLAGS) # avoid DLL having 'lib' prefix with Windows MinGW builds if(WIN32) From 83db02e68da290861cc1ea418f9037f9886f8d9b Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Fri, 9 Jul 2021 11:55:10 +0300 Subject: [PATCH 118/606] cmake: check immintrin.h and set -DSDL_DISABLE_IMMINTRIN_H if necessary just in case. fixes build using older gcc. (yes, I'm being overzealous.) --- CMakeLists.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7dc89f513..7a5db2919 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,6 +39,7 @@ set(SDL12COMPAT_SRCS add_library(SDL SHARED ${SDL12COMPAT_SRCS}) include(CheckCSourceCompiles) +include(CheckIncludeFile) include(CheckCCompilerFlag) include(GNUInstallDirs) @@ -57,6 +58,11 @@ if (CMAKE_C_COMPILER_ID MATCHES "Clang|GNU") set(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Werror=declaration-after-statement") endif() endif() +# just in case: +check_include_file("immintrin.h" HAVE_IMMINTRIN_H) +if(NOT HAVE_IMMINTRIN_H) + set(EXTRA_CFLAGS "${EXTRA_CFLAGS} -DSDL_DISABLE_IMMINTRIN_H") +endif() set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") string(STRIP "${CMAKE_C_FLAGS}" CMAKE_C_FLAGS) From 875e6b58b1911b48303b2831ba2d34c46f4880c2 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Fri, 9 Jul 2021 11:55:10 +0300 Subject: [PATCH 119/606] cmake: fix SDLMain.m filename case. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7a5db2919..905e5c5e1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -125,7 +125,7 @@ endif() # SDLmain library... if(APPLE) - add_library(SDLmain STATIC src/SDLmain/macosx/SDLmain.m) + add_library(SDLmain STATIC src/SDLmain/macosx/SDLMain.m) elseif(WIN32) add_library(SDLmain STATIC src/SDLmain/win32/SDL_win32_main.c) set_target_properties(SDLmain PROPERTIES COMPILE_DEFINITIONS "_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE") # !!! FIXME: don't use C runtime? We fixed this in SDL2. From 51254e57b346666e2835df79823110b2a9acfb1a Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Fri, 9 Jul 2021 11:55:10 +0300 Subject: [PATCH 120/606] cmake: set SDLMain.m source language as C for older cmake. --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 905e5c5e1..14ea7d36a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -126,6 +126,7 @@ endif() # SDLmain library... if(APPLE) add_library(SDLmain STATIC src/SDLmain/macosx/SDLMain.m) + set_source_files_properties(src/SDLmain/macosx/SDLMain.m PROPERTIES LANGUAGE C) elseif(WIN32) add_library(SDLmain STATIC src/SDLmain/win32/SDL_win32_main.c) set_target_properties(SDLmain PROPERTIES COMPILE_DEFINITIONS "_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE") # !!! FIXME: don't use C runtime? We fixed this in SDL2. From 354793dc6a700aa312a6bda66e39f65fd4a2f2ad Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sat, 10 Jul 2021 23:55:02 +0300 Subject: [PATCH 121/606] windows watcom makefile: fixed import library generation --- src/Makefile.w32 | 6 ++++-- src/{SDL12.lbc => SDL12.exports} | 0 2 files changed, 4 insertions(+), 2 deletions(-) rename src/{SDL12.lbc => SDL12.exports} (100%) diff --git a/src/Makefile.w32 b/src/Makefile.w32 index ae610e6f8..bd5bf39fa 100644 --- a/src/Makefile.w32 +++ b/src/Makefile.w32 @@ -47,7 +47,7 @@ $(DLLFILE): compiling_info $(object_files) $(resource_obj) $(LNKFILE) $(LIBFILE): $(DLLFILE) @echo * Creating LIB file: $@ - wlib -q -b -n -c -pa -s -t -zld -ii -io $* $(DLLFILE) + wlib -q -b -n -c -pa -s -t -zld -ii -io $* @SDL12.lbc compiling_info : .symbolic @echo * Compiling... @@ -58,7 +58,8 @@ $(LNKFILE): @%append $@ SYSTEM nt_dll INITINSTANCE TERMINSTANCE @%append $@ NAME $(DLLFILE) @for %i in ($(object_files)) do @%append $@ FILE %i - @%append $@ EXPORT=SDL12.lbc + @%append $@ EXPORT=SDL12.exports + @%append $@ OPTION IMPF=SDL12.lbc @%append $@ OPTION RESOURCE=$(resource_obj) @%append $@ OPTION QUIET @%append $@ OPTION MAP=$^&.map @@ -69,6 +70,7 @@ clean: .SYMBOLIC @echo * Clean: $(LIBNAME) $(VERSION) @if exist *.obj rm *.obj @if exist *.res rm *.res + @if exist *.map rm *.lbc @if exist *.map rm *.map @if exist $(LNKFILE) rm $(LNKFILE) diff --git a/src/SDL12.lbc b/src/SDL12.exports similarity index 100% rename from src/SDL12.lbc rename to src/SDL12.exports From f406f85ef67fc6966af55abdbd1893ada2d78cc9 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sat, 10 Jul 2021 23:55:02 +0300 Subject: [PATCH 122/606] SDL_win32_main.c: removed a left-over definition of isspace() --- src/SDLmain/win32/SDL_win32_main.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/SDLmain/win32/SDL_win32_main.c b/src/SDLmain/win32/SDL_win32_main.c index 7775fdafe..fd7fdfd86 100644 --- a/src/SDLmain/win32/SDL_win32_main.c +++ b/src/SDLmain/win32/SDL_win32_main.c @@ -32,8 +32,6 @@ static int stdioRedirectEnabled = 0; static char stdoutPath[MAX_PATH]; static char stderrPath[MAX_PATH]; -#define isspace(a) (((CHAR)a == ' ') || ((CHAR)a == '\t')) - static void UnEscapeQuotes( char *arg ) { char *last = NULL; From 1cc3061c06877a7ee4277187aa59dcca755e5a7f Mon Sep 17 00:00:00 2001 From: David Gow Date: Thu, 15 Jul 2021 18:16:35 +0800 Subject: [PATCH 123/606] Don't add the 2.0->1.2 event conversion filter twice If the program creates several windows (such as Unreal Tournament 2004's splash screen), the Event Filter used to convert SDL 2.0 events to SDL 1.2 events can end up being added twice, which causes events to be converted twice). Unconditionally remove the event filter in Init12Video() before adding it, to ensure it only ever appears once. This fixes issue #119. --- src/SDL12_compat.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 67fb13326..d7ff76bac 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1734,6 +1734,7 @@ Init12Video(void) SupportSysWM = SDL_FALSE; #endif + SDL20_DelEventWatch(EventFilter20to12, NULL); SDL20_AddEventWatch(EventFilter20to12, NULL); VideoDisplayIndex = GetVideoDisplay(); From 19abb9c06beb987fce147d9aba4db4d228eafee6 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Thu, 15 Jul 2021 21:15:02 +0300 Subject: [PATCH 124/606] testplatform.c: always use %I64 instead of %ll for all windows builds; fixes MinGW gcc warnings: testplatform.c:115:3: warning: unknown conversion type character 'l' in format testplatform.c:115:3: warning: unknown conversion type character 'l' in format testplatform.c:115:3: warning: too many arguments for format --- test/testplatform.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/testplatform.c b/test/testplatform.c index a7b0916a4..aed0f5fd0 100644 --- a/test/testplatform.c +++ b/test/testplatform.c @@ -109,7 +109,7 @@ int TestEndian(SDL_bool verbose) } #ifdef SDL_HAS_64BIT_TYPE if ( verbose ) { -#ifdef _MSC_VER +#ifdef _WIN32 printf("Value 64 = 0x%I64X, swapped = 0x%I64X\n", value64, SDL_Swap64(value64)); #else printf("Value 64 = 0x%llX, swapped = 0x%llX\n", (unsigned long long) value64, (unsigned long long) SDL_Swap64(value64)); From 613fe54f4059073fa2583dc4b77a68758de595ea Mon Sep 17 00:00:00 2001 From: David Gow Date: Mon, 19 Jul 2021 20:50:19 +0800 Subject: [PATCH 125/606] Fix some incorrect scancodes on macOS The A, N, M, and Keypad + and * keys had the wrong scancodes for OS X. A was due to a copy-paste error on my part, whereas N and M were also due to a copy-paste error, but this time in a comment in the DOSBox code. The Keypad + and * keys were an off-by-one in the table. The angle bracket key <> on German QWERTZ layouts still seems to be broken, and will be fixed in a future commit. --- src/SDL12_compat.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index d7ff76bac..c2eb89184 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -2768,7 +2768,7 @@ Scancode20to12(SDL_Scancode sc) CASESCANCODE20TO12(7, 0x10, 0x1A); CASESCANCODE20TO12(8, 0x11, 0x1C); CASESCANCODE20TO12(9, 0x12, 0x19); - CASESCANCODE20TO12(A, 0x26, 0x19); + CASESCANCODE20TO12(A, 0x26, 0x00); CASESCANCODE20TO12(APOSTROPHE, 0x30, 0x27); CASESCANCODE20TO12(B, 0x38, 0x0B); CASESCANCODE20TO12(BACKSLASH, 0x33, 0x2A); @@ -2818,9 +2818,9 @@ Scancode20to12(SDL_Scancode sc) CASESCANCODE20TO12(KP_ENTER, 0x00, 0x4C); CASESCANCODE20TO12(KP_EQUALS, 0x00, 0x51); CASESCANCODE20TO12(KP_MINUS, 0x52, 0x4E); - CASESCANCODE20TO12(KP_MULTIPLY, 0x3F, 0x42); + CASESCANCODE20TO12(KP_MULTIPLY, 0x3F, 0x43); CASESCANCODE20TO12(KP_PERIOD, 0x5B, 0x41); - CASESCANCODE20TO12(KP_PLUS, 0x56, 0x44); + CASESCANCODE20TO12(KP_PLUS, 0x56, 0x45); CASESCANCODE20TO12(L, 0x2E, 0x25); CASESCANCODE20TO12(LALT, 0x40, 0x00); CASESCANCODE20TO12(LCTRL, 0x25, 0x00); @@ -2828,9 +2828,9 @@ Scancode20to12(SDL_Scancode sc) CASESCANCODE20TO12(LEFTBRACKET, 0x22, 0x21); CASESCANCODE20TO12(LGUI, 0x85, 0x00); CASESCANCODE20TO12(LSHIFT, 0x32, 0x00); - CASESCANCODE20TO12(M, 0x3A, 0x29); + CASESCANCODE20TO12(M, 0x3A, 0x2E); CASESCANCODE20TO12(MINUS, 0x14, 0x1B); - CASESCANCODE20TO12(N, 0x39, 0x28); + CASESCANCODE20TO12(N, 0x39, 0x2D); CASESCANCODE20TO12(NUMLOCKCLEAR, 0x4D, 0x47); CASESCANCODE20TO12(O, 0x20, 0x1F); CASESCANCODE20TO12(P, 0x21, 0x23); From aa9919b116ff9a689ace9ab70241f657a9f2da52 Mon Sep 17 00:00:00 2001 From: David Gow Date: Mon, 19 Jul 2021 21:36:14 +0800 Subject: [PATCH 126/606] Add the NONUSBACKSLASH scancode Currently the NONUSBACKSLASH key doesn't map to a scancode at all. It appears to map to 0x32 on macOS[1], and as best I can tell, it is KEY_102ND in Linux/evdev, which is 0x56 (and since we need to add 8, should be 0x5E). DOSBox seems to handle this key specially on Windows (with the 0x56 code, which seems right), and treats it as BACKTICK on macOS. It doesn't seem to be handled at all on Linux (where it might actually be mapped to the right-arrow key if evdev detection fails, so this could introduce a bug here if the SDL_GetWMInfo bits don't work out.) [1] https://github.com/libsdl-org/sdl12-compat/issues/84#issuecomment-882555428 --- src/SDL12_compat.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index c2eb89184..59e8ea835 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -2831,6 +2831,7 @@ Scancode20to12(SDL_Scancode sc) CASESCANCODE20TO12(M, 0x3A, 0x2E); CASESCANCODE20TO12(MINUS, 0x14, 0x1B); CASESCANCODE20TO12(N, 0x39, 0x2D); + CASESCANCODE20TO12(NONUSBACKSLASH, 0x33, 0x2A); CASESCANCODE20TO12(NUMLOCKCLEAR, 0x4D, 0x47); CASESCANCODE20TO12(O, 0x20, 0x1F); CASESCANCODE20TO12(P, 0x21, 0x23); From 0c9c4ffa70457fd35f7a341a8a687c841451d837 Mon Sep 17 00:00:00 2001 From: Sandro Mani Date: Sat, 24 Jul 2021 14:17:55 +0200 Subject: [PATCH 127/606] Add -lmingw32 to SDL_LIBS This prevents undefined references to WinMain@16 by consumers. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 14ea7d36a..61b5a3969 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -234,7 +234,7 @@ if(SDL12DEVEL) if(WIN32) set(SDL_CFLAGS "") set(SDL_RLD_FLAGS "") - set(SDL_LIBS "-lSDLmain -lSDL -mwindows") # -lmingw32 -lSDL -mwindows + set(SDL_LIBS "-lmingw32 -lSDLmain -lSDL -mwindows") set(SDL_STATIC_LIBS "") elseif(APPLE) set(SDL_CFLAGS "-D_THREAD_SAFE") From 35f1a69dcb19f2932b6acf09dca6aa9c6fbd1754 Mon Sep 17 00:00:00 2001 From: David Gow Date: Mon, 26 Jul 2021 11:42:45 +0800 Subject: [PATCH 128/606] Scale relative mouse motion with OpenGL Logical Scaling This makes it match the SDL_Render-based scaling, which does this. The SDL_MOUSE_RELATIVE_SCALING hint is also now supported for OpenGL scaling, again to match the SDL_Render path. It's enabled by default, though obviously is a no-op if OpenGL scaling is not used. Note that this _doesn't quite_ match the SDL_Render version, in that it's not accumulating the remainer. This'll be fixed in a follow-up commit. --- src/SDL12_compat.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 59e8ea835..1354ec386 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -929,6 +929,7 @@ static JoystickOpenedItem JoystickOpenList[16]; static Uint8 KeyState[SDLK12_LAST]; static SDL_bool MouseInputIsRelative = SDL_FALSE; static SDL_Point MousePosition = { 0, 0 }; +static SDL_bool UseMouseRelativeScaling = SDL_FALSE; static OpenGLEntryPoints OpenGLFuncs; static int OpenGLBlitLockCount = 0; static GLuint OpenGLBlitTexture = 0; @@ -2192,6 +2193,7 @@ GetOpenGLLogicalScalingViewport(int physical_width, int physical_height) return dstrect; } +/* Scale a point (e.g. absolute mouse position) to the logical scaling size */ static void AdjustOpenGLLogicalScalingPoint(int *x, int *y) { @@ -2220,6 +2222,30 @@ AdjustOpenGLLogicalScalingPoint(int *x, int *y) *y = SDL_max(SDL_min(adjusted_y, OpenGLLogicalScalingHeight), 0); } +/* Scale a vector (e.g. relative mouse movement) to the logical scaling size */ +static void +AdjustOpenGLLogicalScalingVector(int *x, int *y) +{ + SDL_Rect viewport; + int physical_w, physical_h; + float scale_x, scale_y; + + /* Don't adjust anything if we're not using Logical Scaling */ + if (!OpenGLLogicalScalingFBO) { + return; + } + + /* we want to scale based on the window size, which is dpi-scaled */ + SDL20_GetWindowSize(VideoWindow20, &physical_w, &physical_h); + viewport = GetOpenGLLogicalScalingViewport(physical_w, physical_h); + + scale_x = (float)OpenGLLogicalScalingWidth / viewport.w; + scale_y = (float)OpenGLLogicalScalingHeight / viewport.h; + + *x = (int) (*x * scale_x); + *y = (int) (*y * scale_y); +} + static Uint8 MouseButtonState20to12(const Uint32 state20) { @@ -3129,6 +3155,9 @@ EventFilter20to12(void *data, SDL_Event *event20) AdjustOpenGLLogicalScalingPoint(&event20->motion.x, &event20->motion.y); event12.motion.x = (Uint16) event20->motion.x; event12.motion.y = (Uint16) event20->motion.y; + if (UseMouseRelativeScaling) { + AdjustOpenGLLogicalScalingVector(&event20->motion.xrel, &event20->motion.yrel); + } event12.motion.xrel = (Sint16) event20->motion.xrel; event12.motion.yrel = (Sint16) event20->motion.yrel; if (MouseInputIsRelative) { @@ -4088,6 +4117,12 @@ glCopyTexSubImage3D_shim_for_scaling(GLenum target, GLint level, GLint xoffset, static SDL_bool InitializeOpenGLScaling(const int w, const int h) { + const char *env; + + /* Support the MOUSE_RELATIVE_SCALING hint from SDL 2.0 for OpenGL scaling. */ + env = SDL20_getenv("SDL_MOUSE_RELATIVE_SCALING"); + UseMouseRelativeScaling = (!env || SDL20_atoi(env)) ? SDL_TRUE : SDL_FALSE; + if (!OpenGLFuncs.SUPPORTS_GL_ARB_framebuffer_object) { return SDL_FALSE; /* no FBOs, no scaling. */ } From 23c40739e6d021ec63ba7823598eaacd470a68be Mon Sep 17 00:00:00 2001 From: David Gow Date: Mon, 26 Jul 2021 12:08:47 +0800 Subject: [PATCH 129/606] Improve relative mouse scaling for OpenGL Logical Scaling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To avoid rounding errors accumulating, keep the remainder from converting the scaled relative coordinates from float → int around in a MouseRelativeRemainder variable. This makes it less likely for them to get out-of-sync with the mouse position in non-relative modes, and matches what SDL_Render now does. --- src/SDL12_compat.c | 32 ++++++++++++++++++++++++++++---- src/SDL20_syms.h | 2 ++ 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 1354ec386..62b45033c 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -166,6 +166,11 @@ SDL20_MostSignificantBitIndex32(Uint32 x) #endif } +/* SDL_truncf needs SDL >=2.0.14 (and breaks Watcom), so copy it here */ +static float SDL20_truncf(float x) +{ + return (x < 0.0f) ? SDL20_ceilf(x) : SDL20_floorf(x); +} #define SDL12_DEFAULT_REPEAT_DELAY 500 #define SDL12_DEFAULT_REPEAT_INTERVAL 30 @@ -929,6 +934,7 @@ static JoystickOpenedItem JoystickOpenList[16]; static Uint8 KeyState[SDLK12_LAST]; static SDL_bool MouseInputIsRelative = SDL_FALSE; static SDL_Point MousePosition = { 0, 0 }; +static SDL_FPoint MouseRelativeRemainder = { 0.f, 0.f }; static SDL_bool UseMouseRelativeScaling = SDL_FALSE; static OpenGLEntryPoints OpenGLFuncs; static int OpenGLBlitLockCount = 0; @@ -2224,11 +2230,13 @@ AdjustOpenGLLogicalScalingPoint(int *x, int *y) /* Scale a vector (e.g. relative mouse movement) to the logical scaling size */ static void -AdjustOpenGLLogicalScalingVector(int *x, int *y) +AdjustOpenGLLogicalScalingVector(int *x, int *y, float *rx, float *ry) { SDL_Rect viewport; int physical_w, physical_h; float scale_x, scale_y; + float float_x, float_y; + float trunc_x, trunc_y; /* Don't adjust anything if we're not using Logical Scaling */ if (!OpenGLLogicalScalingFBO) { @@ -2242,8 +2250,21 @@ AdjustOpenGLLogicalScalingVector(int *x, int *y) scale_x = (float)OpenGLLogicalScalingWidth / viewport.w; scale_y = (float)OpenGLLogicalScalingHeight / viewport.h; - *x = (int) (*x * scale_x); - *y = (int) (*y * scale_y); + float_x = *x * scale_x + (rx ? *rx : 0.f); + float_y = *y * scale_y + (ry ? *ry : 0.f); + + trunc_x = SDL20_truncf(float_x); + trunc_y = SDL20_truncf(float_y); + + *x = (int)trunc_x; + *y = (int)trunc_y; + + if (rx) { + *rx = float_x - trunc_x; + } + if (ry) { + *ry = float_y - trunc_y; + } } @@ -3156,7 +3177,10 @@ EventFilter20to12(void *data, SDL_Event *event20) event12.motion.x = (Uint16) event20->motion.x; event12.motion.y = (Uint16) event20->motion.y; if (UseMouseRelativeScaling) { - AdjustOpenGLLogicalScalingVector(&event20->motion.xrel, &event20->motion.yrel); + AdjustOpenGLLogicalScalingVector(&event20->motion.xrel, + &event20->motion.yrel, + &MouseRelativeRemainder.x, + &MouseRelativeRemainder.y); } event12.motion.xrel = (Sint16) event20->motion.xrel; event12.motion.yrel = (Sint16) event20->motion.yrel; diff --git a/src/SDL20_syms.h b/src/SDL20_syms.h index 36ca62487..f1cb7850b 100644 --- a/src/SDL20_syms.h +++ b/src/SDL20_syms.h @@ -308,11 +308,13 @@ SDL20_SYM(int,atoi,(const char *a),(a),return) #ifndef SDL12_MATH #include #define SDL20_fabsf fabs +#define SDL20_ceilf ceil #define SDL20_floorf floor #define SDL12_MATH #endif #else SDL20_SYM(float,fabsf,(float a),(a),return) +SDL20_SYM(float,ceilf,(float a),(a),return) SDL20_SYM(float,floorf,(float a),(a),return) #endif From 71ac21122df59432bea59b7019a2e2f7165b2d67 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Mon, 26 Jul 2021 17:50:50 +0300 Subject: [PATCH 130/606] fix build against recently broken SDL2 headers, i.e. at least SDL_config_windows.h defined HAVE_IMMINTRIN_H without much checking. we actually do not need immintrin.h in sdl12-compat therefore disabled its use in standalone makefiles. some whitespace tidy-ups. --- src/Makefile.darwin | 1 + src/Makefile.linux | 1 + src/Makefile.mingw | 1 + src/Makefile.os2 | 5 +++-- src/Makefile.vc | 1 + src/Makefile.w32 | 3 ++- src/SDL12_compat.c | 7 +++---- 7 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/Makefile.darwin b/src/Makefile.darwin index 019448e12..ddd868772 100644 --- a/src/Makefile.darwin +++ b/src/Makefile.darwin @@ -12,6 +12,7 @@ endif LD = $(CC) CPPFLAGS = -DNDEBUG -D_THREAD_SAFE +CPPFLAGS+= -DSDL_DISABLE_IMMINTRIN_H CFLAGS = -mmacosx-version-min=10.6 -fPIC -O3 -Wall LDFLAGS = -mmacosx-version-min=10.6 -dynamiclib -Wl,-undefined,error -Wl,-single_module diff --git a/src/Makefile.linux b/src/Makefile.linux index f85ca96c2..8a83f5ee8 100644 --- a/src/Makefile.linux +++ b/src/Makefile.linux @@ -8,6 +8,7 @@ CC=gcc LD = $(CC) CPPFLAGS = -DNDEBUG -D_THREAD_SAFE -D_REENTRANT +CPPFLAGS+= -DSDL_DISABLE_IMMINTRIN_H CFLAGS = -fPIC -O3 -Wall LDFLAGS = -shared -Wl,-soname,libSDL-1.2.so.0 diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 1130a9c66..94b5b4273 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -14,6 +14,7 @@ endif LD = $(CC) CPPFLAGS = -DDLL_EXPORT -DNDEBUG +CPPFLAGS+= -DSDL_DISABLE_IMMINTRIN_H CFLAGS = -O3 -Wall LDFLAGS = -nostdlib -shared -Wl,--no-undefined -Wl,--enable-auto-image-base -Wl,--out-implib,$(LIB) diff --git a/src/Makefile.os2 b/src/Makefile.os2 index 4f117c01f..9b8bdfd89 100644 --- a/src/Makefile.os2 +++ b/src/Makefile.os2 @@ -1,5 +1,5 @@ # OpenWatcom makefile to build SDL for OS/2 - +# !ifndef %WATCOM !error Environment variable WATCOM is not specified! !endif @@ -8,7 +8,7 @@ DLLNAME = SDL12 VERSION = 1.2.50 # change SDL2INC to point to the SDL2 headers -SDL2INC = C:\SDL2DEV\h\SDL2 +SDL2INC = include INCPATH = -I"$(%WATCOM)/h/os2" -I"$(%WATCOM)/h" -I"$(SDL2INC)" LIBNAME = $(DLLNAME) @@ -17,6 +17,7 @@ LIBFILE = $(LIBNAME).lib LNKFILE = $(LIBNAME).lnk CFLAGS_DEF=-bt=os2 -d0 -zq -bm -5s -fp5 -fpi87 -sg -oteanbmier $(INCPATH) +CFLAGS_DEF+= -DSDL_DISABLE_IMMINTRIN_H CFLAGS_DLL=$(CFLAGS_DEF) -bd # Special flags for building SDL diff --git a/src/Makefile.vc b/src/Makefile.vc index 8a2cd8e12..d234e1577 100644 --- a/src/Makefile.vc +++ b/src/Makefile.vc @@ -8,6 +8,7 @@ INCLUDES = -Iinclude CPPFLAGS = -DNDEBUG -DDLL_EXPORT +CPPFLAGS = $(CPPFLAGS) -DSDL_DISABLE_IMMINTRIN_H CC = cl LD = link diff --git a/src/Makefile.w32 b/src/Makefile.w32 index bd5bf39fa..af1f65f2b 100644 --- a/src/Makefile.w32 +++ b/src/Makefile.w32 @@ -1,5 +1,5 @@ # OpenWatcom makefile to build SDL for Win32 - +# !ifndef %WATCOM !error Environment variable WATCOM is not specified! !endif @@ -17,6 +17,7 @@ LIBFILE = $(LIBNAME).lib LNKFILE = $(LIBNAME).lnk CFLAGS_DEF=-bt=nt -d0 -zq -bm -5s -fp5 -fpi87 -sg -oteanbmier $(INCPATH) +CFLAGS_DEF+= -DSDL_DISABLE_IMMINTRIN_H # we override the DECLSPEC define in begin_code.h, because we are using # an exports file to remove the _cdecl '_' prefix from the symbol names CFLAGS_DLL=$(CFLAGS_DEF) -bd -DDLL_EXPORT -DDECLSPEC= diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 62b45033c..89663afe3 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -166,7 +166,7 @@ SDL20_MostSignificantBitIndex32(Uint32 x) #endif } -/* SDL_truncf needs SDL >=2.0.14 (and breaks Watcom), so copy it here */ +/* SDL_truncf needs SDL >=2.0.14, so copy it here. */ static float SDL20_truncf(float x) { return (x < 0.0f) ? SDL20_ceilf(x) : SDL20_floorf(x); @@ -2227,7 +2227,7 @@ AdjustOpenGLLogicalScalingPoint(int *x, int *y) *x = SDL_max(SDL_min(adjusted_x, OpenGLLogicalScalingWidth), 0); *y = SDL_max(SDL_min(adjusted_y, OpenGLLogicalScalingHeight), 0); } - + /* Scale a vector (e.g. relative mouse movement) to the logical scaling size */ static void AdjustOpenGLLogicalScalingVector(int *x, int *y, float *rx, float *ry) @@ -2266,7 +2266,6 @@ AdjustOpenGLLogicalScalingVector(int *x, int *y, float *rx, float *ry) *ry = float_y - trunc_y; } } - static Uint8 MouseButtonState20to12(const Uint32 state20) { @@ -2635,7 +2634,7 @@ Keysym20to12(const SDL_Keycode keysym20) FIXME("map some of the SDLK12_WORLD keys"); return SDLK12_UNKNOWN; } -#else +#else /* https://github.com/libsdl-org/sdl12-compat/pull/97 */ # define KeysymFromSDL2(_ev20) Scancode20toKeysym12((_ev20)->key.keysym.scancode) static SDL12Key Scancode20toKeysym12(const SDL_Scancode scancode20) From b6226508974a855f69641143fca28746e9e434fa Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Wed, 28 Jul 2021 14:22:20 +0300 Subject: [PATCH 131/606] provide a default cursor Fixes https://github.com/libsdl-org/sdl12-compat/issues/125 --- src/SDL12_compat.c | 13 ++++- src/default_cursor.h | 114 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 126 insertions(+), 1 deletion(-) create mode 100644 src/default_cursor.h diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 89663afe3..44823f064 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1710,6 +1710,10 @@ Init12VidModes(void) return 0; } +/* we should have a default cursor */ +#include "default_cursor.h" +DECLSPEC void SDLCALL SDL_FreeCursor(SDL12_Cursor *); + static int Init12Video(void) { @@ -1897,7 +1901,7 @@ Quit12Video(void) VideoInfoVfmt20 = NULL; EventFilter12 = NULL; EventQueueAvailable = EventQueueHead = EventQueueTail = NULL; - CurrentCursor12 = NULL; + SDL_FreeCursor(CurrentCursor12); VideoModes = NULL; VideoModesCount = 0; } @@ -3788,6 +3792,9 @@ SDL_ListModes(const SDL12_PixelFormat *format12, Uint32 flags) DECLSPEC void SDLCALL SDL_FreeCursor(SDL12_Cursor *cursor12) { + if (cursor12 == CurrentCursor12) { + CurrentCursor12 = NULL; + } if (cursor12) { if (cursor12->wm_cursor) { SDL20_FreeCursor(cursor12->wm_cursor); @@ -3857,6 +3864,10 @@ SDL_SetCursor(SDL12_Cursor *cursor) DECLSPEC SDL12_Cursor * SDLCALL SDL_GetCursor(void) { + if (!CurrentCursor12) { + CurrentCursor12 = SDL_CreateCursor(default_cdata, default_cmask, + DEFAULT_CWIDTH, DEFAULT_CHEIGHT, DEFAULT_CHOTX, DEFAULT_CHOTY); + } return CurrentCursor12; } diff --git a/src/default_cursor.h b/src/default_cursor.h new file mode 100644 index 000000000..0a888f4c8 --- /dev/null +++ b/src/default_cursor.h @@ -0,0 +1,114 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2021 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Default cursor - it happens to be the Mac cursor, but could be anything */ + +#define DEFAULT_CWIDTH 16 +#define DEFAULT_CHEIGHT 16 +#define DEFAULT_CHOTX 0 +#define DEFAULT_CHOTY 0 + +/* Added a real MacOS cursor, at the request of Luc-Olivier de Charrière */ +#define USE_MACOS_CURSOR + +#ifdef USE_MACOS_CURSOR + +static unsigned char default_cdata[] = { + 0x00, 0x00, + 0x40, 0x00, + 0x60, 0x00, + 0x70, 0x00, + 0x78, 0x00, + 0x7C, 0x00, + 0x7E, 0x00, + 0x7F, 0x00, + 0x7F, 0x80, + 0x7C, 0x00, + 0x6C, 0x00, + 0x46, 0x00, + 0x06, 0x00, + 0x03, 0x00, + 0x03, 0x00, + 0x00, 0x00 +}; + +static unsigned char default_cmask[] = { + 0xC0, 0x00, + 0xE0, 0x00, + 0xF0, 0x00, + 0xF8, 0x00, + 0xFC, 0x00, + 0xFE, 0x00, + 0xFF, 0x00, + 0xFF, 0x80, + 0xFF, 0xC0, + 0xFF, 0xE0, + 0xFE, 0x00, + 0xEF, 0x00, + 0xCF, 0x00, + 0x87, 0x80, + 0x07, 0x80, + 0x03, 0x00 +}; + +#else + +static unsigned char default_cdata[] = { + 0x00, 0x00, + 0x40, 0x00, + 0x60, 0x00, + 0x70, 0x00, + 0x78, 0x00, + 0x7C, 0x00, + 0x7E, 0x00, + 0x7F, 0x00, + 0x7F, 0x80, + 0x7C, 0x00, + 0x6C, 0x00, + 0x46, 0x00, + 0x06, 0x00, + 0x03, 0x00, + 0x03, 0x00, + 0x00, 0x00 +}; + +static unsigned char default_cmask[] = { + 0x40, 0x00, + 0xE0, 0x00, + 0xF0, 0x00, + 0xF8, 0x00, + 0xFC, 0x00, + 0xFE, 0x00, + 0xFF, 0x00, + 0xFF, 0x80, + 0xFF, 0xC0, + 0xFF, 0x80, + 0xFE, 0x00, + 0xEF, 0x00, + 0x4F, 0x00, + 0x07, 0x80, + 0x07, 0x80, + 0x03, 0x00 +}; + +#endif /* USE_MACOS_CURSOR */ +/* vi: set ts=4 sw=4 expandtab: */ From 87c7e298b0a97d65acf576de69440b820bdb6e03 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Fri, 30 Jul 2021 23:25:24 +0300 Subject: [PATCH 132/606] replace size_t casts to pointers with intptr_t. --- src/SDL12_compat.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 44823f064..9b5475487 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -36,6 +36,12 @@ #include #include +#include +#if defined(_MSC_VER) && (_MSC_VER < 1600) +/* intptr_t already handled by stddef.h. */ +#else +#include +#endif #ifdef _WIN32 #ifndef WIN32_LEAN_AND_MEAN @@ -6198,7 +6204,7 @@ static Sint64 SDLCALL RWops12to20_size(struct SDL_RWops *rwops20) { SDL12_RWops *rwops12 = (SDL12_RWops *) rwops20->hidden.unknown.data1; - int size = (int) ((size_t) rwops20->hidden.unknown.data2); + int size = (int) ((intptr_t) rwops20->hidden.unknown.data2); int pos; if (size != -1) { @@ -6211,7 +6217,7 @@ RWops12to20_size(struct SDL_RWops *rwops20) } size = rwops12->seek(rwops12, 0, RW_SEEK_END); rwops12->seek(rwops12, pos, RW_SEEK_SET); - rwops20->hidden.unknown.data2 = (void *) ((size_t) size); + rwops20->hidden.unknown.data2 = (void *) ((intptr_t) size); return size; } @@ -6276,7 +6282,7 @@ RWops12to20(SDL12_RWops *rwops12) SDL20_zerop(rwops20); rwops20->type = rwops12->type; rwops20->hidden.unknown.data1 = rwops12; - rwops20->hidden.unknown.data2 = (void *) ((size_t) -1); /* cached size of stream */ + rwops20->hidden.unknown.data2 = (void *) ((intptr_t) -1); /* cached size of stream */ rwops20->size = RWops12to20_size; rwops20->seek = RWops12to20_seek; rwops20->read = RWops12to20_read; From 1592b565751c387851d479a9d87931981bac4251 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Thu, 5 Aug 2021 21:20:02 +0300 Subject: [PATCH 133/606] dr_mp3.h: minor updates from mainstream. --- src/dr_mp3.h | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/dr_mp3.h b/src/dr_mp3.h index b2e20f0af..6d5bb5ef4 100644 --- a/src/dr_mp3.h +++ b/src/dr_mp3.h @@ -1,6 +1,6 @@ /* MP3 audio decoder. Choice of public domain or MIT-0. See license statements at the end of this file. -dr_mp3 - v0.6.27 - 2021-02-21 +dr_mp3 - v0.6.28 - 2021-07-31 David Reid - mackron@gmail.com @@ -101,7 +101,7 @@ extern "C" { #define DRMP3_VERSION_MAJOR 0 #define DRMP3_VERSION_MINOR 6 -#define DRMP3_VERSION_REVISION 27 +#define DRMP3_VERSION_REVISION 28 #define DRMP3_VERSION_STRING DRMP3_XSTRINGIFY(DRMP3_VERSION_MAJOR) "." DRMP3_XSTRINGIFY(DRMP3_VERSION_MINOR) "." DRMP3_XSTRINGIFY(DRMP3_VERSION_REVISION) #include /* For size_t. */ @@ -130,7 +130,7 @@ typedef unsigned int drmp3_uint32; #pragma GCC diagnostic pop #endif #endif -#if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__)) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__) +#if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__)) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(_M_ARM64) || defined(__powerpc64__) typedef drmp3_uint64 drmp3_uintptr; #else typedef drmp3_uint32 drmp3_uintptr; @@ -718,7 +718,7 @@ static int drmp3_have_simd(void) #if defined(__ARM_ARCH) && (__ARM_ARCH >= 6) && !defined(__aarch64__) && !defined(_M_ARM64) #define DRMP3_HAVE_ARMV6 1 -static __inline__ __attribute__((always_inline)) drmp3_int32 drmp3_clip_int16_arm(int32_t a) +static __inline__ __attribute__((always_inline)) drmp3_int32 drmp3_clip_int16_arm(drmp3_int32 a) { drmp3_int32 x = 0; __asm__ ("ssat %0, #16, %1" : "=r"(x) : "r"(a)); @@ -4479,6 +4479,10 @@ counts rather than sample counts. /* REVISION HISTORY ================ +v0.6.28 - 2021-07-31 + - Fix platform detection for ARM64. + - Fix a compilation error with C89. + v0.6.27 - 2021-02-21 - Fix a warning due to referencing _MSC_VER when it is undefined. From 69b591c03d5cfc884925a0a916ba95e2d25441eb Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sun, 8 Aug 2021 23:51:56 +0300 Subject: [PATCH 134/606] dr_mp3.h: minor updates from mainstream. --- src/dr_mp3.h | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/src/dr_mp3.h b/src/dr_mp3.h index 6d5bb5ef4..2cb5a719c 100644 --- a/src/dr_mp3.h +++ b/src/dr_mp3.h @@ -1,6 +1,6 @@ /* MP3 audio decoder. Choice of public domain or MIT-0. See license statements at the end of this file. -dr_mp3 - v0.6.28 - 2021-07-31 +dr_mp3 - v0.6.29 - 2021-08-08 David Reid - mackron@gmail.com @@ -101,7 +101,7 @@ extern "C" { #define DRMP3_VERSION_MAJOR 0 #define DRMP3_VERSION_MINOR 6 -#define DRMP3_VERSION_REVISION 28 +#define DRMP3_VERSION_REVISION 29 #define DRMP3_VERSION_STRING DRMP3_XSTRINGIFY(DRMP3_VERSION_MAJOR) "." DRMP3_XSTRINGIFY(DRMP3_VERSION_MINOR) "." DRMP3_XSTRINGIFY(DRMP3_VERSION_REVISION) #include /* For size_t. */ @@ -1407,12 +1407,22 @@ static void drmp3_L3_midside_stereo(float *left, int n) int i = 0; float *right = left + 576; #if DRMP3_HAVE_SIMD - if (drmp3_have_simd()) for (; i < n - 3; i += 4) + if (drmp3_have_simd()) { - drmp3_f4 vl = DRMP3_VLD(left + i); - drmp3_f4 vr = DRMP3_VLD(right + i); - DRMP3_VSTORE(left + i, DRMP3_VADD(vl, vr)); - DRMP3_VSTORE(right + i, DRMP3_VSUB(vl, vr)); + for (; i < n - 3; i += 4) + { + drmp3_f4 vl = DRMP3_VLD(left + i); + drmp3_f4 vr = DRMP3_VLD(right + i); + DRMP3_VSTORE(left + i, DRMP3_VADD(vl, vr)); + DRMP3_VSTORE(right + i, DRMP3_VSUB(vl, vr)); + } +#ifdef __GNUC__ + /* Workaround for spurious -Waggressive-loop-optimizations warning from gcc. + * For more info see: https://github.com/lieff/minimp3/issues/88 + */ + if (__builtin_constant_p(n % 4 == 0) && n % 4 == 0) + return; +#endif } #endif for (; i < n; i++) @@ -4479,6 +4489,9 @@ counts rather than sample counts. /* REVISION HISTORY ================ +v0.6.29 - 2021-08-08 + - Bring up to date with minimp3. + v0.6.28 - 2021-07-31 - Fix platform detection for ARM64. - Fix a compilation error with C89. From 4337edad510bebb3c8be16e0c22222de008fdafa Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 10 Aug 2021 21:42:38 -0400 Subject: [PATCH 135/606] README.md: minor updates --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 56cbc9cdb..88b677d6f 100644 --- a/README.md +++ b/README.md @@ -6,10 +6,10 @@ This is the Simple DirectMedia Layer, a general API that provides low level access to audio, keyboard, mouse, joystick, 3D hardware via OpenGL, and 2D framebuffer across multiple platforms. -This code is a compatibility layer; it provides a binary-compatible API for -programs written against SDL 1.2, but it uses SDL 2.0 behind the scenes. If -you are writing new code, please target SDL 2.0 directly and do not use this -layer. +This code is a compatibility layer; it provides a binary and source +compatible API for programs written against SDL 1.2, but it uses SDL 2.0 +behind the scenes. If you are writing new code, please target SDL 2.0 +directly and do not use this layer. If you absolutely must have the real SDL 1.2 ("SDL 1.2 Classic"), please use the source tree at https://github.com/libsdl-org/SDL-1.2, which occasionally @@ -18,8 +18,8 @@ that. # How to use: -- Build the library. This will need access to SDL2's headers, CMake -( https://cmake.org/ ) and the build tools of your choice. Once built, you +- Build the library. This will need access to SDL2's headers, +[CMake](https://cmake.org/) and the build tools of your choice. Once built, you will have a drop-in replacement that can be used with any existing binary that relies on SDL 1.2. You can copy this library over the existing 1.2 build, or force it to take priority over a system copy with LD_LIBRARY_PATH, etc. From ddc6727b0fbcfb9b6c3a9aea4f097a86c202d396 Mon Sep 17 00:00:00 2001 From: David Gow Date: Fri, 13 Aug 2021 15:14:59 +0800 Subject: [PATCH 136/606] Do not generate VIDEORESIZE events on SIZE_CHANGED The recommended way to handle VIDEORESIZE is with a new SDL_SetVideoMode() call, and creating a new window generates a SIZE_CHANGED event, which leads to an infinite loop. The other main case for SIZE_CHANGED events is when the screen resolution is changed out from underneath a fullscreen window, and we handle that with the logical scaling. So it doesn't appear that there's any use for SIZE_CHANGED events in SDL 1.2 applications. So let's just ignore them. This fixes Drawf Fortress in bug #127. --- src/SDL12_compat.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 9b5475487..52995679e 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -2991,8 +2991,11 @@ EventFilter20to12(void *data, SDL_Event *event20) break; case SDL_WINDOWEVENT_RESIZED: - case SDL_WINDOWEVENT_SIZE_CHANGED: - FIXME("what's the difference between RESIZED and SIZE_CHANGED?"); + /* don't generate a VIDEORESIZE event based on SIZE_CHANGED + events: the recommended way to handle VIDEORESIZE is + with a new SDL_SetVideoMode() call, and creating a new + window generates a SIZE_CHANGED event, which leads to an + infinite loop. */ /* don't report VIDEORESIZE if we're fullscreen-desktop; we're doing logical scaling and as far as the app is From a3bfcb2f85ec6477c4bc54585c1749934e6486d4 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sun, 15 Aug 2021 02:02:28 +0300 Subject: [PATCH 137/606] mp3: replace direct uses of memset, memcpy and memmove by DRMP3_* macros (patch submitted to mainstream as https://github.com/mackron/dr_libs/pull/199) --- src/SDL12_compat.c | 16 +-------- src/dr_mp3.h | 85 ++++++++++++++++++++++++---------------------- 2 files changed, 45 insertions(+), 56 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 52995679e..14404e7a5 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -6374,23 +6374,9 @@ SDL_LoadWAV_RW(SDL12_RWops *rwops12, int freerwops12, #define DRMP3_REALLOC(p, sz) SDL20_realloc((p), (sz)) #define DRMP3_FREE(p) SDL20_free((p)) #define DRMP3_COPY_MEMORY(dst, src, sz) SDL20_memcpy((dst), (src), (sz)) +#define DRMP3_MOVE_MEMORY(dst, src, sz) SDL20_memmove((dst), (src), (sz)) #define DRMP3_ZERO_MEMORY(p, sz) SDL20_memset((p), 0, (sz)) -#if !defined(__clang_analyzer__) -#ifdef memset -#undef memset -#endif -#ifdef memcpy -#undef memcpy -#endif -#ifdef memmove -#undef memmove -#endif -#define memset SDL20_memset -#define memcpy SDL20_memcpy -#define memmove SDL20_memmove -#endif - #include "dr_mp3.h" static size_t diff --git a/src/dr_mp3.h b/src/dr_mp3.h index 2cb5a719c..9714eb646 100644 --- a/src/dr_mp3.h +++ b/src/dr_mp3.h @@ -729,6 +729,31 @@ static __inline__ __attribute__((always_inline)) drmp3_int32 drmp3_clip_int16_ar #endif +/* Standard library stuff. */ +#ifndef DRMP3_ASSERT +#include +#define DRMP3_ASSERT(expression) assert(expression) +#endif +#ifndef DRMP3_COPY_MEMORY +#define DRMP3_COPY_MEMORY(dst, src, sz) memcpy((dst), (src), (sz)) +#endif +#ifndef DRMP3_MOVE_MEMORY +#define DRMP3_MOVE_MEMORY(dst, src, sz) memmove((dst), (src), (sz)) +#endif +#ifndef DRMP3_ZERO_MEMORY +#define DRMP3_ZERO_MEMORY(p, sz) memset((p), 0, (sz)) +#endif +#define DRMP3_ZERO_OBJECT(p) DRMP3_ZERO_MEMORY((p), sizeof(*(p))) +#ifndef DRMP3_MALLOC +#define DRMP3_MALLOC(sz) malloc((sz)) +#endif +#ifndef DRMP3_REALLOC +#define DRMP3_REALLOC(p, sz) realloc((p), (sz)) +#endif +#ifndef DRMP3_FREE +#define DRMP3_FREE(p) free((p)) +#endif + typedef struct { const drmp3_uint8 *buf; @@ -995,7 +1020,7 @@ static int drmp3_L12_dequantize_granule(float *grbuf, drmp3_bs *bs, drmp3_L12_sc static void drmp3_L12_apply_scf_384(drmp3_L12_scale_info *sci, const float *scf, float *dst) { int i, k; - memcpy(dst + 576 + sci->stereo_bands*18, dst + sci->stereo_bands*18, (sci->total_bands - sci->stereo_bands)*18*sizeof(float)); + DRMP3_COPY_MEMORY(dst + 576 + sci->stereo_bands*18, dst + sci->stereo_bands*18, (sci->total_bands - sci->stereo_bands)*18*sizeof(float)); for (i = 0; i < sci->total_bands; i++, dst += 18, scf += 6) { for (k = 0; k < 12; k++) @@ -1140,14 +1165,14 @@ static void drmp3_L3_read_scalefactors(drmp3_uint8 *scf, drmp3_uint8 *ist_pos, c int cnt = scf_count[i]; if (scfsi & 8) { - memcpy(scf, ist_pos, cnt); + DRMP3_COPY_MEMORY(scf, ist_pos, cnt); } else { int bits = scf_size[i]; if (!bits) { - memset(scf, 0, cnt); - memset(ist_pos, 0, cnt); + DRMP3_ZERO_MEMORY(scf, cnt); + DRMP3_ZERO_MEMORY(ist_pos, cnt); } else { int max_scf = (scfsi < 0) ? (1 << bits) - 1 : -1; @@ -1532,7 +1557,7 @@ static void drmp3_L3_reorder(float *grbuf, float *scratch, const drmp3_uint8 *sf *dst++ = src[2*len]; } } - memcpy(grbuf, scratch, (dst - scratch)*sizeof(float)); + DRMP3_COPY_MEMORY(grbuf, scratch, (dst - scratch)*sizeof(float)); } static void drmp3_L3_antialias(float *grbuf, int nbands) @@ -1701,8 +1726,8 @@ static void drmp3_L3_imdct_short(float *grbuf, float *overlap, int nbands) for (;nbands > 0; nbands--, overlap += 9, grbuf += 18) { float tmp[18]; - memcpy(tmp, grbuf, sizeof(tmp)); - memcpy(grbuf, overlap, 6*sizeof(float)); + DRMP3_COPY_MEMORY(tmp, grbuf, sizeof(tmp)); + DRMP3_COPY_MEMORY(grbuf, overlap, 6*sizeof(float)); drmp3_L3_imdct12(tmp, grbuf + 6, overlap + 6); drmp3_L3_imdct12(tmp + 1, grbuf + 12, overlap + 6); drmp3_L3_imdct12(tmp + 2, overlap, overlap + 6); @@ -1746,7 +1771,7 @@ static void drmp3_L3_save_reservoir(drmp3dec *h, drmp3dec_scratch *s) } if (remains > 0) { - memmove(h->reserv_buf, s->maindata + pos, remains); + DRMP3_MOVE_MEMORY(h->reserv_buf, s->maindata + pos, remains); } h->reserv = remains; } @@ -1755,8 +1780,8 @@ static int drmp3_L3_restore_reservoir(drmp3dec *h, drmp3_bs *bs, drmp3dec_scratc { int frame_bytes = (bs->limit - bs->pos)/8; int bytes_have = DRMP3_MIN(h->reserv, main_data_begin); - memcpy(s->maindata, h->reserv_buf + DRMP3_MAX(0, h->reserv - main_data_begin), DRMP3_MIN(h->reserv, main_data_begin)); - memcpy(s->maindata + bytes_have, bs->buf + bs->pos/8, frame_bytes); + DRMP3_COPY_MEMORY(s->maindata, h->reserv_buf + DRMP3_MAX(0, h->reserv - main_data_begin), DRMP3_MIN(h->reserv, main_data_begin)); + DRMP3_COPY_MEMORY(s->maindata + bytes_have, bs->buf + bs->pos/8, frame_bytes); drmp3_bs_init(&s->bs, s->maindata, bytes_have + frame_bytes); return h->reserv >= main_data_begin; } @@ -2163,7 +2188,7 @@ static void drmp3d_synth_granule(float *qmf_state, float *grbuf, int nbands, int drmp3d_DCT_II(grbuf + 576*i, nbands); } - memcpy(lins, qmf_state, sizeof(float)*15*64); + DRMP3_COPY_MEMORY(lins, qmf_state, sizeof(float)*15*64); for (i = 0; i < nbands; i += 2) { @@ -2179,7 +2204,7 @@ static void drmp3d_synth_granule(float *qmf_state, float *grbuf, int nbands, int } else #endif { - memcpy(qmf_state, lins + nbands*64, sizeof(float)*15*64); + DRMP3_COPY_MEMORY(qmf_state, lins + nbands*64, sizeof(float)*15*64); } } @@ -2257,7 +2282,7 @@ DRMP3_API int drmp3dec_decode_frame(drmp3dec *dec, const drmp3_uint8 *mp3, int m } if (!frame_size) { - memset(dec, 0, sizeof(drmp3dec)); + DRMP3_ZERO_MEMORY(dec, sizeof(drmp3dec)); i = drmp3d_find_frame(mp3, mp3_bytes, &dec->free_format_bytes, &frame_size); if (!frame_size || i + frame_size > mp3_bytes) { @@ -2267,7 +2292,7 @@ DRMP3_API int drmp3dec_decode_frame(drmp3dec *dec, const drmp3_uint8 *mp3, int m } hdr = mp3 + i; - memcpy(dec->header, hdr, DRMP3_HDR_SIZE); + DRMP3_COPY_MEMORY(dec->header, hdr, DRMP3_HDR_SIZE); info->frame_bytes = i + frame_size; info->channels = DRMP3_HDR_IS_MONO(hdr) ? 1 : 2; info->hz = drmp3_hdr_sample_rate_hz(hdr); @@ -2293,7 +2318,7 @@ DRMP3_API int drmp3dec_decode_frame(drmp3dec *dec, const drmp3_uint8 *mp3, int m { for (igr = 0; igr < (DRMP3_HDR_TEST_MPEG1(hdr) ? 2 : 1); igr++, pcm = DRMP3_OFFSET_PTR(pcm, sizeof(drmp3d_sample_t)*576*info->channels)) { - memset(scratch.grbuf[0], 0, 576*2*sizeof(float)); + DRMP3_ZERO_MEMORY(scratch.grbuf[0], 576*2*sizeof(float)); drmp3_L3_decode(dec, &scratch, scratch.gr_info + igr*info->channels, info->channels); drmp3d_synth_granule(dec->qmf_state, scratch.grbuf[0], 18, info->channels, (drmp3d_sample_t*)pcm, scratch.syn[0]); } @@ -2312,7 +2337,7 @@ DRMP3_API int drmp3dec_decode_frame(drmp3dec *dec, const drmp3_uint8 *mp3, int m drmp3_L12_read_scale_info(hdr, bs_frame, sci); - memset(scratch.grbuf[0], 0, 576*2*sizeof(float)); + DRMP3_ZERO_MEMORY(scratch.grbuf[0], 576*2*sizeof(float)); for (i = 0, igr = 0; igr < 3; igr++) { if (12 == (i += drmp3_L12_dequantize_granule(scratch.grbuf[0] + i, bs_frame, sci, info->layer | 1))) @@ -2320,7 +2345,7 @@ DRMP3_API int drmp3dec_decode_frame(drmp3dec *dec, const drmp3_uint8 *mp3, int m i = 0; drmp3_L12_apply_scf_384(sci, sci->scf + igr, scratch.grbuf[0]); drmp3d_synth_granule(dec->qmf_state, scratch.grbuf[0], 12, info->channels, (drmp3d_sample_t*)pcm, scratch.syn[0]); - memset(scratch.grbuf[0], 0, 576*2*sizeof(float)); + DRMP3_ZERO_MEMORY(scratch.grbuf[0], 576*2*sizeof(float)); pcm = DRMP3_OFFSET_PTR(pcm, sizeof(drmp3d_sample_t)*384*info->channels); } if (bs_frame->pos > bs_frame->limit) @@ -2426,28 +2451,6 @@ DRMP3_API void drmp3dec_f32_to_s16(const float *in, drmp3_int16 *out, size_t num #endif -/* Standard library stuff. */ -#ifndef DRMP3_ASSERT -#include -#define DRMP3_ASSERT(expression) assert(expression) -#endif -#ifndef DRMP3_COPY_MEMORY -#define DRMP3_COPY_MEMORY(dst, src, sz) memcpy((dst), (src), (sz)) -#endif -#ifndef DRMP3_ZERO_MEMORY -#define DRMP3_ZERO_MEMORY(p, sz) memset((p), 0, (sz)) -#endif -#define DRMP3_ZERO_OBJECT(p) DRMP3_ZERO_MEMORY((p), sizeof(*(p))) -#ifndef DRMP3_MALLOC -#define DRMP3_MALLOC(sz) malloc((sz)) -#endif -#ifndef DRMP3_REALLOC -#define DRMP3_REALLOC(p, sz) realloc((p), (sz)) -#endif -#ifndef DRMP3_FREE -#define DRMP3_FREE(p) free((p)) -#endif - #define DRMP3_COUNTOF(x) (sizeof(x) / sizeof(x[0])) #define DRMP3_CLAMP(x, lo, hi) (DRMP3_MAX(lo, DRMP3_MIN(x, hi))) @@ -2679,7 +2682,7 @@ static drmp3_uint32 drmp3_decode_next_frame_ex__callbacks(drmp3* pMP3, drmp3d_sa /* First we need to move the data down. */ if (pMP3->pData != NULL) { - memmove(pMP3->pData, pMP3->pData + pMP3->dataConsumed, pMP3->dataSize); + DRMP3_MOVE_MEMORY(pMP3->pData, pMP3->pData + pMP3->dataConsumed, pMP3->dataSize); } pMP3->dataConsumed = 0; @@ -2739,7 +2742,7 @@ static drmp3_uint32 drmp3_decode_next_frame_ex__callbacks(drmp3* pMP3, drmp3d_sa size_t bytesRead; /* First we need to move the data down. */ - memmove(pMP3->pData, pMP3->pData + pMP3->dataConsumed, pMP3->dataSize); + DRMP3_MOVE_MEMORY(pMP3->pData, pMP3->pData + pMP3->dataConsumed, pMP3->dataSize); pMP3->dataConsumed = 0; if (pMP3->dataCapacity == pMP3->dataSize) { From d77661a4db2fa7bbcaea753074ca7c8e8d9ad834 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Mon, 23 Aug 2021 00:02:50 +0300 Subject: [PATCH 138/606] dr_mp3.h: updates from mainstream. --- src/dr_mp3.h | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/src/dr_mp3.h b/src/dr_mp3.h index 9714eb646..56344ad2e 100644 --- a/src/dr_mp3.h +++ b/src/dr_mp3.h @@ -1,6 +1,6 @@ /* MP3 audio decoder. Choice of public domain or MIT-0. See license statements at the end of this file. -dr_mp3 - v0.6.29 - 2021-08-08 +dr_mp3 - v0.6.31 - 2021-08-22 David Reid - mackron@gmail.com @@ -101,7 +101,7 @@ extern "C" { #define DRMP3_VERSION_MAJOR 0 #define DRMP3_VERSION_MINOR 6 -#define DRMP3_VERSION_REVISION 29 +#define DRMP3_VERSION_REVISION 31 #define DRMP3_VERSION_STRING DRMP3_XSTRINGIFY(DRMP3_VERSION_MAJOR) "." DRMP3_XSTRINGIFY(DRMP3_VERSION_MINOR) "." DRMP3_XSTRINGIFY(DRMP3_VERSION_REVISION) #include /* For size_t. */ @@ -2787,12 +2787,22 @@ static drmp3_uint32 drmp3_decode_next_frame_ex__memory(drmp3* pMP3, drmp3d_sampl return 0; } - pcmFramesRead = drmp3dec_decode_frame(&pMP3->decoder, pMP3->memory.pData + pMP3->memory.currentReadPos, (int)(pMP3->memory.dataSize - pMP3->memory.currentReadPos), pPCMFrames, &info); - if (pcmFramesRead > 0) { - pMP3->pcmFramesConsumedInMP3Frame = 0; - pMP3->pcmFramesRemainingInMP3Frame = pcmFramesRead; - pMP3->mp3FrameChannels = info.channels; - pMP3->mp3FrameSampleRate = info.hz; + for (;;) { + pcmFramesRead = drmp3dec_decode_frame(&pMP3->decoder, pMP3->memory.pData + pMP3->memory.currentReadPos, (int)(pMP3->memory.dataSize - pMP3->memory.currentReadPos), pPCMFrames, &info); + if (pcmFramesRead > 0) { + pcmFramesRead = drmp3_hdr_frame_samples(pMP3->decoder.header); + pMP3->pcmFramesConsumedInMP3Frame = 0; + pMP3->pcmFramesRemainingInMP3Frame = pcmFramesRead; + pMP3->mp3FrameChannels = info.channels; + pMP3->mp3FrameSampleRate = info.hz; + break; + } else if (info.frame_bytes > 0) { + /* No frames were read, but it looks like we skipped past one. Read the next MP3 frame. */ + pMP3->memory.currentReadPos += (size_t)info.frame_bytes; + } else { + /* Nothing at all was read. Abort. */ + break; + } } /* Consume the data. */ @@ -2855,7 +2865,7 @@ static drmp3_bool32 drmp3_init_internal(drmp3* pMP3, drmp3_read_proc onRead, drm } /* Decode the first frame to confirm that it is indeed a valid MP3 stream. */ - if (!drmp3_decode_next_frame(pMP3)) { + if (drmp3_decode_next_frame(pMP3) == 0) { drmp3__free_from_callbacks(pMP3->pData, &pMP3->allocationCallbacks); /* The call above may have allocated memory. Need to make sure it's freed before aborting. */ return DRMP3_FALSE; /* Not a valid MP3 stream. */ } @@ -4492,6 +4502,13 @@ counts rather than sample counts. /* REVISION HISTORY ================ +v0.6.31 - 2021-08-22 + - Fix a bug when loading from memory. + +v0.6.30 - 2021-08-16 + - Silence some warnings. + - Replace memory operations with DRMP3_* macros. + v0.6.29 - 2021-08-08 - Bring up to date with minimp3. From e1da54fdfb721d5a615c25e1bd5063110a58b401 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 25 Aug 2021 10:49:36 -0400 Subject: [PATCH 139/606] SDL_UpdateRects: Only lock parts of texture we intend to update. Previously we would lock the entire texture, but this is a misuse of SDL2's API, as it doesn't promise to preserve locked portions that you don't write to during the lock, and the Metal renderer definitely doesn't. Fixes #130. --- src/SDL12_compat.c | 74 ++++++++++++++++++++++++---------------------- 1 file changed, 39 insertions(+), 35 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 14404e7a5..d672a9ecd 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -5021,52 +5021,56 @@ SDL_UpdateRects(SDL12_Surface *surface12, int numrects, SDL12_Rect *rects12) * but in practice most apps never got a double-buffered surface and * don't handle it correctly, so we have to work around it. */ if (surface12 == VideoSurface12) { + SDL_Palette *logicalPal = surface12->surface20->format->palette; + const int pixsize = surface12->format->BytesPerPixel; + const int srcpitch = surface12->pitch; SDL_bool whole_screen = SDL_FALSE; - SDL_Rect rect20; void *pixels = NULL; + SDL_Rect rect20; int pitch = 0; - int i; + int i, j; - if (SDL20_LockTexture(VideoTexture20, NULL, &pixels, &pitch) < 0) { - return; /* oh well */ - } + for (i = 0; i < numrects; i++) { + UpdateRect12to20(surface12, &rects12[i], &rect20, &whole_screen); + if (!rect20.w || !rect20.h) { + continue; + } else if (SDL20_LockTexture(VideoTexture20, &rect20, &pixels, &pitch) < 0) { + continue; /* oh well */ + } - if (VideoConvertSurface20) { - SDL_Palette *logicalPal = surface12->surface20->format->palette; - surface12->surface20->format->palette = VideoPhysicalPalette20; - VideoConvertSurface20->pixels = pixels; - VideoConvertSurface20->pitch = pitch; - for (i = 0; i < numrects; i++) { - UpdateRect12to20(surface12, &rects12[i], &rect20, &whole_screen); - if (rect20.w && rect20.h) { - SDL20_UpperBlit(VideoSurface12->surface20, &rect20, VideoConvertSurface20, &rect20); + if (VideoConvertSurface20) { + SDL_Rect dstrect20; /* pretend that the subregion is just the top left of the convert surface. */ + dstrect20.x = dstrect20.y = 0; + dstrect20.w = rect20.w; + dstrect20.h = rect20.h; + surface12->surface20->format->palette = VideoPhysicalPalette20; + VideoConvertSurface20->pixels = pixels; + VideoConvertSurface20->pitch = pitch; + VideoConvertSurface20->w = rect20.w; + VideoConvertSurface20->h = rect20.h; + SDL20_UpperBlit(VideoSurface12->surface20, &rect20, VideoConvertSurface20, &dstrect20); + } else { + const int cpy = rect20.w * pixsize; + char *dst = pixels; + const Uint8 *src = (((Uint8 *) surface12->pixels) + (rect20.y * srcpitch)) + (rect20.x * pixsize); + for (j = 0; j < rect20.h; j++) { + SDL20_memcpy(dst, src, cpy); + src += srcpitch; + dst += pitch; } } + + SDL20_UnlockTexture(VideoTexture20); + } + + if (VideoConvertSurface20) { /* reset some state we messed with */ + surface12->surface20->format->palette = logicalPal; VideoConvertSurface20->pixels = NULL; VideoConvertSurface20->pitch = 0; - surface12->surface20->format->palette = logicalPal; - } else { - const int srcpitch = surface12->pitch; - const int pixsize = surface12->format->BytesPerPixel; - for (i = 0; i < numrects; i++) { - UpdateRect12to20(surface12, &rects12[i], &rect20, &whole_screen); - if (rect20.w && rect20.h) { - const int cpy = rect20.w * pixsize; - const int h = surface12->h; - char *dst = (((char *) pixels) + (rect20.y * pitch)) + (rect20.x * pixsize); - char *src = (((char *) surface12->pixels) + (rect20.y * srcpitch)) + (rect20.x * pixsize); - int j = 0; - for (; j < h; j++) { - SDL20_memcpy(dst, src, cpy); - src += srcpitch; - dst += pitch; - } - } - } + VideoConvertSurface20->w = VideoSurface12->w; + VideoConvertSurface20->h = VideoSurface12->h; } - SDL20_UnlockTexture(VideoTexture20); - if (whole_screen) { PresentScreen(); /* flip it now. */ } else { From b5f7170c430f8c54f913caaea7c587dcec06bfc1 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Wed, 25 Aug 2021 20:20:02 +0300 Subject: [PATCH 140/606] added missing cast to assignment --- src/SDL12_compat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index d672a9ecd..a00d3fa3a 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -5051,7 +5051,7 @@ SDL_UpdateRects(SDL12_Surface *surface12, int numrects, SDL12_Rect *rects12) SDL20_UpperBlit(VideoSurface12->surface20, &rect20, VideoConvertSurface20, &dstrect20); } else { const int cpy = rect20.w * pixsize; - char *dst = pixels; + char *dst = (char *) pixels; const Uint8 *src = (((Uint8 *) surface12->pixels) + (rect20.y * srcpitch)) + (rect20.x * pixsize); for (j = 0; j < rect20.h; j++) { SDL20_memcpy(dst, src, cpy); From 0888ba8bd207f6edd62418150fbcbc64ecf78e3c Mon Sep 17 00:00:00 2001 From: David Gow Date: Sat, 14 Aug 2021 17:58:59 +0800 Subject: [PATCH 141/606] Don't recreate the window on resize, even in windowed mode Resizable SDL 1.2 windows are really annoying to use when the window gets repeatedly recreated, as (at least on some window managers) this resets the resize operation. --- src/SDL12_compat.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index a00d3fa3a..3f9cfd0b5 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -4324,8 +4324,6 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12) EndVidModeCreate(); /* rebuild the window if moving to/from a GL context */ } else if (VideoSurface12 && (VideoSurface12->surface20->format->format != appfmt)) { EndVidModeCreate(); /* rebuild the window if changing pixel format */ - } else if (VideoSurface12 && (VideoSurface12->w != width || VideoSurface12->h != height) && ((flags12 & SDL12_FULLSCREEN) == 0)) { - EndVidModeCreate(); /* rebuild the window if window size changed and not in full screen */ } else if (VideoGLContext20) { /* SDL 1.2 (infuriatingly!) destroys the GL context on each resize, so we will too */ SDL20_GL_MakeCurrent(NULL, NULL); From dae11192d8439769480acbcbf7709d9beb475646 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Wed, 1 Sep 2021 17:56:28 +0300 Subject: [PATCH 142/606] build fix: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SDL12_compat.c:587: error: using typedef-name ‘SDL_SYSWM_TYPE’ after ‘enum’ /opt/SDL2/include/SDL2/SDL_syswm.h:147: error: ‘SDL_SYSWM_TYPE’ has a previous declaration here this showed itself only in c++ mode.. --- src/SDL12_compat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 3f9cfd0b5..9331d4c92 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -584,7 +584,7 @@ typedef struct SDL12_keysym #define SDL12_PRESSED 1 #if defined(SDL_VIDEO_DRIVER_X11) /* SDL_VIDEO_DRIVER_X11 refers to the SDL2 headers. */ -typedef enum SDL_SYSWM_TYPE /* this is only used for 1.2 X11 syswm */ +typedef enum /* this is only used for 1.2 X11 syswm */ { SDL12_SYSWM_X11 } SDL12_SYSWM_TYPE; From a98590a0d9176806b4f21fe2fbb35107b427cf67 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Fri, 10 Sep 2021 01:11:20 +0300 Subject: [PATCH 143/606] version requirement clarifications: It appears that headers from SDL2 >= 2.0.7 are needed for SDL_AudioStream in order to build. At runtime, 2.0.9 or newer needed (2.0.12+ for windows because of an SDL_Thread compatibility issue.) Documented these. Moved SDL2 version check from SDL12_compat.c to SDL20_include_wrapper.h and bumped its minimum requirement from 2.0.0 to 2.0.7. Removed use of SDL_FPoint struct, so that we can compile against versions as old as 2.0.7. Closes: https://github.com/libsdl-org/sdl12-compat/issues/131 --- README.md | 8 ++++---- src/SDL12_compat.c | 8 +++----- src/SDL20_include_wrapper.h | 6 ++++++ 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 88b677d6f..ccf21cafe 100644 --- a/README.md +++ b/README.md @@ -18,13 +18,14 @@ that. # How to use: -- Build the library. This will need access to SDL2's headers, +- Build the library. This will need access to SDL2's headers (v2.0.7 or newer), [CMake](https://cmake.org/) and the build tools of your choice. Once built, you will have a drop-in replacement that can be used with any existing binary that relies on SDL 1.2. You can copy this library over the existing 1.2 build, or force it to take priority over a system copy with LD_LIBRARY_PATH, etc. -At runtime, sdl12-compat needs to be able to find a copy of SDL2, so plan to -include it with the library if necessary. +At runtime, sdl12-compat needs to be able to find a copy of SDL2 (v2.0.9 or +newer -- v2.0.12 or newer for Windows), so plan to include it with the library +if necessary. - If you want to build an SDL 1.2 program from source code, we have included compatibility headers, so that sdl12-compat can completely replace SDL 1.2 @@ -33,4 +34,3 @@ compatibility and don't have a lot of documentation or fanciness at all. The new headers are also under the zlib license. Note that sdl12-compat itself does not use these headers, so if you just want the library, you don't need them. - diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 9331d4c92..d55f19240 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -23,10 +23,6 @@ #include "SDL20_include_wrapper.h" -#if !SDL_VERSION_ATLEAST(2,0,0) -#error You need to compile against SDL 2.0 headers. -#endif - /* * We report the library version as 1.2.$(SDL12_COMPAT_VERSION). This number * should be way ahead of what SDL-1.2 Classic would report, so apps can @@ -940,7 +936,9 @@ static JoystickOpenedItem JoystickOpenList[16]; static Uint8 KeyState[SDLK12_LAST]; static SDL_bool MouseInputIsRelative = SDL_FALSE; static SDL_Point MousePosition = { 0, 0 }; -static SDL_FPoint MouseRelativeRemainder = { 0.f, 0.f }; +static struct { /* SDL_FPoint */ + float x, y; +} MouseRelativeRemainder = { 0.f, 0.f }; static SDL_bool UseMouseRelativeScaling = SDL_FALSE; static OpenGLEntryPoints OpenGLFuncs; static int OpenGLBlitLockCount = 0; diff --git a/src/SDL20_include_wrapper.h b/src/SDL20_include_wrapper.h index 5316cda83..cfd1d8414 100644 --- a/src/SDL20_include_wrapper.h +++ b/src/SDL20_include_wrapper.h @@ -116,6 +116,12 @@ #include "SDL.h" #include "SDL_syswm.h" /* includes windows.h for _WIN32, os2.h for __OS2__ */ +/* Headers from SDL2 >= 2.0.7 needed for SDL_AudioStream: + */ +#if !SDL_VERSION_ATLEAST(2,0,7) +#error You need to compile against SDL >= 2.0.7 headers. +#endif + /* Missing SDL_thread.h stuff (see above): */ #if defined(_WIN32) || defined(__OS2__) typedef struct SDL_Thread SDL_Thread; From c6cfc8f7f258f5f1a505e4f92198fd6bd3fbbc90 Mon Sep 17 00:00:00 2001 From: David Gow Date: Sun, 26 Sep 2021 16:00:31 +0800 Subject: [PATCH 144/606] Support SDL12COMPAT_SYNC_TO_VBLANK for OpenGL apps For non-OpenGL applications, the SDL12COMPAT_SYNC_TO_VBLANK environment variable could be used to enable/disable VSync. For OpenGL applications, this was always able to be controlled by the application, using the SDL_GL_SWAP_CONTROL attribute. However, some old games do not provide a simple mechanism for configuring VSync (and so either don't set SDL_GL_SWAP_CONTROL, or always set it to an undesirable value). Allow the SDL12COMPAT_SYNC_TO_VBLANK environment variable to override the SDL_GL_SWAP_CONTROL attribute for OpenGL windows. The existing behaviour remains if SDL12COMPAT_SYNC_TO_VBLANK is not set. (Also remove a FIXME() which was obsolete.) --- src/SDL12_compat.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index d55f19240..6bde98d14 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -4408,6 +4408,7 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12) } if (flags12 & SDL12_OPENGL) { + const char *vsync_env = SDL20_getenv("SDL12COMPAT_SYNC_TO_VBLANK"); SDL_assert(!VideoTexture20); /* either a new window or we destroyed all this */ SDL_assert(!VideoRenderer20); FIXME("Should we force a compatibility context here?"); @@ -4456,7 +4457,11 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12) VideoSurface12->flags |= SDL12_OPENGLBLIT; } - SDL20_GL_SetSwapInterval(SwapInterval); + if (vsync_env) { + SDL20_GL_SetSwapInterval(SDL20_atoi(vsync_env)); + } else { + SDL20_GL_SetSwapInterval(SwapInterval); + } } else { /* always use a renderer for non-OpenGL windows. */ @@ -5728,7 +5733,6 @@ SDL_GL_SetAttribute(SDL12_GLattr attr, int value) /* swap control was moved out of this API, everything else lines up. */ if (attr == SDL12_GL_SWAP_CONTROL) { SwapInterval = value; - FIXME("Actually set swap interval somewhere"); return 0; } else if (attr == SDL12_GL_MULTISAMPLESAMPLES) { From aba4b033c348ce8747b98898acbb1b6fb2f062ad Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Fri, 15 Oct 2021 10:15:00 +0300 Subject: [PATCH 145/606] make things work against SDL-2.0.9 at run time. --- src/SDL12_compat.c | 10 ++++++++++ src/SDL20_syms.h | 6 ------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 6bde98d14..403dc845d 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -6383,6 +6383,16 @@ SDL_LoadWAV_RW(SDL12_RWops *rwops12, int freerwops12, #include "dr_mp3.h" +static SDL_INLINE Sint64 SDLCALL SDL20_RWseek(SDL_RWops *ctx, Sint64 ofs, int whence) { + return ctx->seek(ctx, ofs, whence); +} +static SDL_INLINE size_t SDLCALL SDL20_RWread(SDL_RWops *ctx, void *ptr, size_t size, size_t n) { + return ctx->read(ctx, ptr, size, n); +} +static SDL_INLINE int SDLCALL SDL20_RWclose(SDL_RWops *ctx) { + return ctx->close(ctx); +} + static size_t mp3_sdlrwops_read(void *data, void *buf, size_t bytesToRead) { diff --git a/src/SDL20_syms.h b/src/SDL20_syms.h index f1cb7850b..374b2cc66 100644 --- a/src/SDL20_syms.h +++ b/src/SDL20_syms.h @@ -253,12 +253,6 @@ SDL20_SYM(SDL_RWops *,RWFromMem,(void *a, int b),(a,b),return) SDL20_SYM(SDL_RWops *,RWFromConstMem,(const void *a, int b),(a,b),return) SDL20_SYM(SDL_RWops *,AllocRW,(void),(),return) SDL20_SYM(void,FreeRW,(SDL_RWops *a),(a),) -SDL20_SYM(Sint64,RWsize,(SDL_RWops *a),(a),return) -SDL20_SYM(Sint64,RWseek,(SDL_RWops *a, Sint64 b, int c),(a,b,c),return) -SDL20_SYM(Sint64,RWtell,(SDL_RWops *a),(a),return) -SDL20_SYM(size_t,RWread,(SDL_RWops *a, void *b, size_t c, size_t d),(a,b,c,d),return) -SDL20_SYM(size_t,RWwrite,(SDL_RWops *a, const void *b, size_t c, size_t d),(a,b,c,d),return) -SDL20_SYM(int,RWclose,(SDL_RWops *a),(a),return) SDL20_SYM_PASSTHROUGH(void *,malloc,(size_t a),(a),return) SDL20_SYM_PASSTHROUGH(void *,calloc,(size_t a, size_t b),(a,b),return) From bf73424b68cd2b90de4dc813b2de70e4097d36a5 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Fri, 15 Oct 2021 18:56:20 +0300 Subject: [PATCH 146/606] support SDL2 versions down to 2.0.7 Closes: https://github.com/libsdl-org/sdl12-compat/issues/134 --- README.md | 2 +- src/SDL12_compat.c | 24 +++++++++++------------- src/SDL20_syms.h | 13 ++++++------- 3 files changed, 18 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index ccf21cafe..c2af48cca 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ that. will have a drop-in replacement that can be used with any existing binary that relies on SDL 1.2. You can copy this library over the existing 1.2 build, or force it to take priority over a system copy with LD_LIBRARY_PATH, etc. -At runtime, sdl12-compat needs to be able to find a copy of SDL2 (v2.0.9 or +At runtime, sdl12-compat needs to be able to find a copy of SDL2 (v2.0.7 or newer -- v2.0.12 or newer for Windows), so plan to include it with the library if necessary. diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 403dc845d..e9e12b462 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -171,7 +171,7 @@ SDL20_MostSignificantBitIndex32(Uint32 x) /* SDL_truncf needs SDL >=2.0.14, so copy it here. */ static float SDL20_truncf(float x) { - return (x < 0.0f) ? SDL20_ceilf(x) : SDL20_floorf(x); + return (x < 0.0f) ? (float)SDL20_ceil(x) : (float)SDL20_floor(x); } #define SDL12_DEFAULT_REPEAT_DELAY 500 @@ -989,7 +989,7 @@ static char loaderror[256]; #include #define DIRSEP "\\" #define SDL20_LIBNAME "SDL2.dll" - #define SDL20_REQUIRED_VER SDL_VERSIONNUM(2,0,9) + #define SDL20_REQUIRED_VER SDL_VERSIONNUM(2,0,7) #define strcpy_fn strcpy #define sprintf_fn sprintf static HMODULE Loaded_SDL20 = NULLHANDLE; @@ -1017,7 +1017,7 @@ static char loaderror[256]; #include #define SDL20_LIBNAME "libSDL2-2.0.0.dylib" #define SDL20_FRAMEWORK "SDL2.framework/Versions/A/SDL2" - #define SDL20_REQUIRED_VER SDL_VERSIONNUM(2,0,9) + #define SDL20_REQUIRED_VER SDL_VERSIONNUM(2,0,7) #define strcpy_fn strcpy #define sprintf_fn sprintf static void *Loaded_SDL20 = NULL; @@ -1068,7 +1068,7 @@ static char loaderror[256]; #elif defined(__unix__) #include #define SDL20_LIBNAME "libSDL2-2.0.so.0" - #define SDL20_REQUIRED_VER SDL_VERSIONNUM(2,0,9) + #define SDL20_REQUIRED_VER SDL_VERSIONNUM(2,0,7) static void *Loaded_SDL20 = NULL; #define LoadSDL20Library() ((Loaded_SDL20 = dlopen(SDL20_LIBNAME, RTLD_LOCAL|RTLD_NOW)) != NULL) #define LookupSDL20Sym(sym) dlsym(Loaded_SDL20, sym) @@ -2182,7 +2182,7 @@ GetOpenGLLogicalScalingViewport(int physical_width, int physical_height) want_aspect = ((float) OpenGLLogicalScalingWidth) / ((float) OpenGLLogicalScalingHeight); real_aspect = ((float) physical_width) / ((float) physical_height); - if (SDL20_fabsf(want_aspect-real_aspect) < 0.0001f) { + if (SDL20_fabs(want_aspect-real_aspect) < 0.0001) { /* The aspect ratios are the same, just scale appropriately */ dstrect.x = 0; dstrect.y = 0; @@ -2193,14 +2193,14 @@ GetOpenGLLogicalScalingViewport(int physical_width, int physical_height) const float scale = ((float) physical_width) / OpenGLLogicalScalingWidth; dstrect.x = 0; dstrect.w = physical_width; - dstrect.h = (int)SDL20_floorf(OpenGLLogicalScalingHeight * scale); + dstrect.h = (int)SDL20_floor(OpenGLLogicalScalingHeight * scale); dstrect.y = (physical_height - dstrect.h) / 2; } else { /* We want a narrower aspect ratio than is available - use side-bars */ const float scale = ((float)physical_height) / OpenGLLogicalScalingHeight; dstrect.y = 0; dstrect.h = physical_height; - dstrect.w = (int)SDL20_floorf(OpenGLLogicalScalingWidth * scale); + dstrect.w = (int)SDL20_floor(OpenGLLogicalScalingWidth * scale); dstrect.x = (physical_width - dstrect.w) / 2; } @@ -3429,12 +3429,10 @@ Surface20to12(SDL_Surface *surface20) format12->Bmask = surface20->format->Bmask; format12->Amask = surface20->format->Amask; - if (SDL20_HasColorKey(surface20)) { - if (SDL20_GetColorKey(surface20, &format12->colorkey) < 0) { - format12->colorkey = 0; - } else { - surface12->flags |= SDL12_SRCCOLORKEY; - } + if (SDL20_GetColorKey(surface20, &format12->colorkey) < 0) { + format12->colorkey = 0; + } else { + surface12->flags |= SDL12_SRCCOLORKEY; } if (SDL20_GetSurfaceAlphaMod(surface20, &format12->alpha) < 0) { diff --git a/src/SDL20_syms.h b/src/SDL20_syms.h index 374b2cc66..343ce434e 100644 --- a/src/SDL20_syms.h +++ b/src/SDL20_syms.h @@ -113,7 +113,6 @@ SDL20_SYM(void,UnlockSurface,(SDL_Surface *a),(a),) SDL20_SYM(int,UpperBlit,(SDL_Surface *a,const SDL_Rect *b,SDL_Surface *c, SDL_Rect *d),(a,b,c,d),return) SDL20_SYM(int,LowerBlit,(SDL_Surface *a,const SDL_Rect *b,SDL_Surface *c, SDL_Rect *d),(a,b,c,d),return) SDL20_SYM(int,SoftStretch,(SDL_Surface *a,const SDL_Rect *b,SDL_Surface *c,const SDL_Rect *d),(a,b,c,d),return) -SDL20_SYM(SDL_bool,HasColorKey,(SDL_Surface *a),(a),return) SDL20_SYM(int,SetColorKey,(SDL_Surface *a, int b, Uint32 c),(a,b,c),return) SDL20_SYM(int,GetColorKey,(SDL_Surface *a, Uint32 *b),(a,b),return) SDL20_SYM(void,FreeSurface,(SDL_Surface *a),(a),) @@ -301,15 +300,15 @@ SDL20_SYM(int,atoi,(const char *a),(a),return) #ifdef __WATCOMC__ /* Watcom builds are broken with SDL math functions. */ #ifndef SDL12_MATH #include -#define SDL20_fabsf fabs -#define SDL20_ceilf ceil -#define SDL20_floorf floor +#define SDL20_fabs fabs +#define SDL20_ceil ceil +#define SDL20_floor floor #define SDL12_MATH #endif #else -SDL20_SYM(float,fabsf,(float a),(a),return) -SDL20_SYM(float,ceilf,(float a),(a),return) -SDL20_SYM(float,floorf,(float a),(a),return) +SDL20_SYM(double,fabs,(double a),(a),return) +SDL20_SYM(double,ceil,(double a),(a),return) +SDL20_SYM(double,floor,(double a),(a),return) #endif SDL20_SYM(SDL_Renderer *,CreateRenderer,(SDL_Window *a, int b, Uint32 c),(a,b,c),return) From 36a09e450a007c86ed0f91812fbbba0d783be120 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Fri, 15 Oct 2021 18:56:40 +0300 Subject: [PATCH 147/606] SDL_atoi() before SDL2-2.0.17 is non-compliant. --- src/SDL12_compat.c | 7 +++++++ src/SDL20_syms.h | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index e9e12b462..8e553fcc4 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -972,6 +972,13 @@ static EventQueueType *EventQueueAvailable = NULL; /* This is a KEYDOWN event which is being held for a follow-up TEXTINPUT */ static SDL12_Event PendingKeydownEvent; +/* SDL_atoi() before SDL2-2.0.17 is non-compliant */ +static SDL_INLINE int SDLCALL +SDL20_atoi(const char *str) +{ + return SDL20_strtol(str, NULL, 10); +} + /* Obviously we can't use SDL_LoadObject() to load SDL2. :) */ static char loaderror[256]; #if defined(_WIN32) diff --git a/src/SDL20_syms.h b/src/SDL20_syms.h index 343ce434e..417e325f5 100644 --- a/src/SDL20_syms.h +++ b/src/SDL20_syms.h @@ -296,7 +296,7 @@ SDL20_SYM_PASSTHROUGH(int,iconv_close,(SDL_iconv_t a),(a),return) SDL20_SYM_PASSTHROUGH(size_t,iconv,(SDL_iconv_t a, const char **b, size_t *c, char **d, size_t *e),(a,b,c,d,e),return) SDL20_SYM_PASSTHROUGH(char *,iconv_string,(const char *a, const char *b, const char *c, size_t d),(a,b,c,d),return) SDL20_SYM(int,setenv,(const char *a, const char *b, int c),(a,b,c),return) -SDL20_SYM(int,atoi,(const char *a),(a),return) + #ifdef __WATCOMC__ /* Watcom builds are broken with SDL math functions. */ #ifndef SDL12_MATH #include From ad396b9a028f3576585f38cd3c0e4934cc7d8d9d Mon Sep 17 00:00:00 2001 From: David Gow Date: Fri, 5 Nov 2021 22:46:55 +0800 Subject: [PATCH 148/606] Add SDL12COMPAT_USE_KEYBOARD_LAYOUT hint SDL 1.2 seems to only account for (non-en_US) keyboard layouts on some platforms and configurations. In particular, the KeySym may contain the translated key, or may contain a "scancode" which is layout-independent. In particular, on X11 the configured layout is used, but only (it seems) if it is the only configured layout. (On systems where multiple layouts are configured, the US layout is used regardless of the configured one.) Similarly, the windib backend deliberately forces the US layout in order to match the DirectX backend, which only provides scancodes. Since this behaviour is very inconsistant between different configurations, this patch provides a way of configuring which is used at runtime: If the SDL12COMPAT_USE_KEYBOARD_LAYOUT environment variable is set to a nonzero value, sdl12compat will translate keyboard input according to the current layout. This matches SDL 1.2 on X11 with only one configured layout. Otherwise (the default), sdl12compat will use SDL2 scancodes for keyboard input, essentially forcing all input to the US layout. This matches SDL 1.2 on Windows, and on X11 with multiple configured layouts. Regardless of the value of this environment variable, the 'unicode' value will be affected by keyboard layout. For discussion and more details see: - sdl12compat issue #135: Non-US Keyboard layouts not supported https://github.com/libsdl-org/sdl12-compat/issues/135 - sdl12compat PR #97: Use Scancodes instead of Keycodes https://github.com/libsdl-org/sdl12-compat/pull/97 - SDL 1.2 issue #95: windib returns locale dependent SDLK_ codes https://github.com/libsdl-org/SDL-1.2/issues/95 --- src/SDL12_compat.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 8e553fcc4..d52359532 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -923,6 +923,7 @@ static char *WindowTitle = NULL; static char *WindowIconTitle = NULL; static SDL_Surface *VideoIcon20 = NULL; static int EnabledUnicode = 0; +static SDL_bool TranslateKeyboardLayout = SDL_FALSE; static int VideoDisplayIndex = 0; static SDL_bool SupportSysWM = SDL_FALSE; static SDL_bool CDRomInit = SDL_FALSE; @@ -1729,9 +1730,12 @@ static int Init12Video(void) { const char *driver = SDL20_GetCurrentVideoDriver(); + const char *layout_env = SDL20_getenv("SDL12COMPAT_USE_KEYBOARD_LAYOUT"); SDL_DisplayMode mode; int i; + TranslateKeyboardLayout = (!layout_env || SDL20_atoi(layout_env)) ? SDL_TRUE : SDL_FALSE; + IsDummyVideo = ((driver != NULL) && (SDL20_strcmp(driver, "dummy") == 0)) ? SDL_TRUE : SDL_FALSE; for (i = 0; i < SDL12_MAXEVENTS-1; i++) @@ -2561,8 +2565,6 @@ SDL_GetKeyName(SDL12Key key) return (char *) "unknown key"; } -#if 0 /* https://github.com/libsdl-org/sdl12-compat/pull/97 */ -# define KeysymFromSDL2(_ev20) Keysym20to12((_ev20)->key.keysym.sym) static SDL12Key Keysym20to12(const SDL_Keycode keysym20) { @@ -2649,8 +2651,6 @@ Keysym20to12(const SDL_Keycode keysym20) FIXME("map some of the SDLK12_WORLD keys"); return SDLK12_UNKNOWN; } -#else /* https://github.com/libsdl-org/sdl12-compat/pull/97 */ -# define KeysymFromSDL2(_ev20) Scancode20toKeysym12((_ev20)->key.keysym.scancode) static SDL12Key Scancode20toKeysym12(const SDL_Scancode scancode20) { @@ -2795,7 +2795,6 @@ Scancode20toKeysym12(const SDL_Scancode scancode20) FIXME("map some of the SDLK12_WORLD keys"); return SDLK12_UNKNOWN; } -#endif static Uint8 Scancode20to12(SDL_Scancode sc) @@ -3086,7 +3085,12 @@ EventFilter20to12(void *data, SDL_Event *event20) if (event20->key.repeat) { return 1; /* ignore 2.0-style key repeat events */ } - event12.key.keysym.sym = KeysymFromSDL2(event20); + + if (TranslateKeyboardLayout) { + event12.key.keysym.sym = Keysym20to12(event20->key.keysym.sym); + } else { + event12.key.keysym.sym = Scancode20toKeysym12(event20->key.keysym.scancode); + } KeyState[event12.key.keysym.sym] = event20->key.state; @@ -3108,7 +3112,11 @@ EventFilter20to12(void *data, SDL_Event *event20) return 1; /* ignore 2.0-style key repeat events */ } - PendingKeydownEvent.key.keysym.sym = KeysymFromSDL2(event20); + if (TranslateKeyboardLayout) { + PendingKeydownEvent.key.keysym.sym = Keysym20to12(event20->key.keysym.sym); + } else { + PendingKeydownEvent.key.keysym.sym = Scancode20toKeysym12(event20->key.keysym.scancode); + } KeyState[PendingKeydownEvent.key.keysym.sym] = event20->key.state; From 782fa833f4ab903a17863dde71106f98c76964bd Mon Sep 17 00:00:00 2001 From: David Gow Date: Sun, 7 Nov 2021 15:01:38 +0800 Subject: [PATCH 149/606] Make SDL12COMPAT_USE_KEYBOARD_LAYOUT's default platform-specific. It looks like (at least out of the top three of Windows, Mac, and Linux), only Windows forces the use of the US layout. Mac (at least from a cursory reading of the code), translates according to the keyboard layout, as does X11 (albeit with some bugs). In this case, set the default to disable layout translation only on Win32, and have it enabled by default on other platforms. This does break DOSBox, but only when "usescancodes = false" (or potentially if keyboard layouts changed some of the non-printable character keys which would break out scancode fallback). Since this is not the default, hopefully people won't encounter it...? --- src/SDL12_compat.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index d52359532..4eb8c5ce6 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -923,7 +923,17 @@ static char *WindowTitle = NULL; static char *WindowIconTitle = NULL; static SDL_Surface *VideoIcon20 = NULL; static int EnabledUnicode = 0; +/* Windows SDL1.2 never uses translated keyboard layouts for compatibility with +DirectInput, which didn't support them. Other platforms (MacOS, Linux) seem to, +but with varying levels of bugginess. So default to Translated Layouts on +all non-Windows platforms (but have an option to change this, as many apps are +buggy with non-US layouts, or provide their own keyboard layout translation, +such as DOSBox. */ +#if !defined(_WIN32) +static SDL_bool TranslateKeyboardLayout = SDL_TRUE; +#else static SDL_bool TranslateKeyboardLayout = SDL_FALSE; +#endif static int VideoDisplayIndex = 0; static SDL_bool SupportSysWM = SDL_FALSE; static SDL_bool CDRomInit = SDL_FALSE; @@ -1734,7 +1744,10 @@ Init12Video(void) SDL_DisplayMode mode; int i; - TranslateKeyboardLayout = (!layout_env || SDL20_atoi(layout_env)) ? SDL_TRUE : SDL_FALSE; + /* Only override this if the env var is set, as the default is platform-specific. */ + if (layout_env) { + TranslateKeyboardLayout = SDL20_atoi(layout_env) ? SDL_TRUE : SDL_FALSE; + } IsDummyVideo = ((driver != NULL) && (SDL20_strcmp(driver, "dummy") == 0)) ? SDL_TRUE : SDL_FALSE; From dd127db58761ede740f45d7bd38592bd81b3520c Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sun, 7 Nov 2021 12:50:20 +0300 Subject: [PATCH 150/606] renamed SDL12_COMPAT_DEBUG_LOGGING to SDL12COMPAT_DEBUG_LOGGING for consistency --- src/SDL12_compat.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 4eb8c5ce6..49d87f492 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1142,7 +1142,7 @@ LoadSDL20(void) if (!okay) { sprintf_fn(loaderror, "SDL2 %d.%d.%d library is too old.", v.major, v.minor, v.patch); } else { - const char *envr = SDL20_getenv("SDL12_COMPAT_DEBUG_LOGGING"); + const char *envr = SDL20_getenv("SDL12COMPAT_DEBUG_LOGGING"); const SDL_bool debug_logging = (!envr || (SDL20_atoi(envr) == 0)) ? SDL_FALSE : SDL_TRUE; #if ENABLE_FIXMES == 1 PrintFixmes = debug_logging; @@ -1637,7 +1637,7 @@ Init12VidModes(void) int i, j; SDL12_Rect prev_mode = { 0, 0, 0, 0 }, current_mode = { 0, 0, 0, 0 }; /* We only want to enable fake modes if OpenGL Logical Scaling is enabled. */ - char *env = SDL20_getenv("SDL12COMPAT_OPENGL_SCALING"); + const char *env = SDL20_getenv("SDL12COMPAT_OPENGL_SCALING"); SDL_bool use_fake_modes = (!env || SDL20_atoi(env)) ? SDL_TRUE : SDL_FALSE; if (VideoModesCount > 0) { From 26f0539a6162efedc1e281fca8ddd718a0eb6feb Mon Sep 17 00:00:00 2001 From: Daniel Gibson Date: Sun, 7 Nov 2021 18:37:08 +0100 Subject: [PATCH 151/606] Fix SDL1.2 scancode for SDL_SCANCODE_NONUSBACKSLASH This is definitely correct on ISO layouts on Linux (I checked with a real SDL1.2), the Mac situation is a bit confusing, as the virtual keycode of the key that is at the SDL_SCANCODE_GRAVE position on ANSI layouts is at the SDL_SCANCODE_NONUSBACKSLASH position on ISO layouts and the _GRAVE key has a different virtual keycode (0x0A) then. For reference, https://stackoverflow.com/a/16125341/14633188 has an image with Mac Virtual Keycodes, from MacintoshToolboxEssentials.pdf (page 2-43 or 87) --- src/SDL12_compat.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 49d87f492..297ca4e7a 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -2870,7 +2870,7 @@ Scancode20to12(SDL_Scancode sc) CASESCANCODE20TO12(F8, 0x4A, 0x64); CASESCANCODE20TO12(F9, 0x4B, 0x65); CASESCANCODE20TO12(G, 0x2A, 0x05); - CASESCANCODE20TO12(GRAVE, 0x31, 0x32); + CASESCANCODE20TO12(GRAVE, 0x31, 0x32); /* Note: the mac scancode might not be 100% correct, see below */ CASESCANCODE20TO12(H, 0x2B, 0x04); CASESCANCODE20TO12(HOME, 0x00, 0x73); CASESCANCODE20TO12(I, 0x1F, 0x22); @@ -2904,7 +2904,11 @@ Scancode20to12(SDL_Scancode sc) CASESCANCODE20TO12(M, 0x3A, 0x2E); CASESCANCODE20TO12(MINUS, 0x14, 0x1B); CASESCANCODE20TO12(N, 0x39, 0x2D); - CASESCANCODE20TO12(NONUSBACKSLASH, 0x33, 0x2A); + /* On Macs with ANSI layout, 0x32 is SDL_SCANCODE_GRAVE and _NONUSBACKSLASH doesn't exist. + * On Macs with ISO layout, 0x32 is _NONUSBACKSLASH and 0x0A is the key at the position of _GRAVE.. + * Probably it's best to keep _GRAVE at 0x32 and use 0x0A for _NONUSBACKSLASH instead, + * so at least it has a unique scancode at all. */ + CASESCANCODE20TO12(NONUSBACKSLASH, 0x5E, 0x0A); CASESCANCODE20TO12(NUMLOCKCLEAR, 0x4D, 0x47); CASESCANCODE20TO12(O, 0x20, 0x1F); CASESCANCODE20TO12(P, 0x21, 0x23); From 3600c872531ddead438446cb4c725cd49eff5871 Mon Sep 17 00:00:00 2001 From: Daniel Gibson Date: Sun, 7 Nov 2021 22:08:18 +0100 Subject: [PATCH 152/606] Support SDLK_WORLD_* keys The corresponding keys (should) have UCS-4 codes as SDL2-KeyCodes, so match UCS-4-codes to the low byte of the corresponding X11 KeySym, which is what SDL1.2 did, at least on X11, see https://github.com/libsdl-org/SDL-1.2/blob/15f4b475f70cb71be5e8e96a032ce2874723d524/src/video/x11/SDL_x11events.c#L1177-L1192 (and for other platforms it's at least better than nothing). --- src/SDL12_compat.c | 657 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 655 insertions(+), 2 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 297ca4e7a..fde1a4de8 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -2581,7 +2581,9 @@ SDL_GetKeyName(SDL12Key key) static SDL12Key Keysym20to12(const SDL_Keycode keysym20) { - if (((int) keysym20) < 127) { /* (most of) low-ASCII maps directly */ + if (((int) keysym20) <= 255) { + /* (most of) low-ASCII maps directly, + * and so does the Latin-1 range (128-255) */ if (keysym20 == SDLK_PAUSE) { return SDLK12_PAUSE; } else if (keysym20 == SDLK_CLEAR) { @@ -2657,11 +2659,662 @@ Keysym20to12(const SDL_Keycode keysym20) CASEKEYSYM20TO12(POWER); CASEKEYSYM20TO12(UNDO); #undef CASEKEYSYM20TO12 + + /* Map the "World Keys" (SDLK_WORLD_0 = 0xA0 to SDLK_WORLD_95 = 0xFF). + * In SDL2 they're the UCS-4 (32bit unicode) code for the key, + * in SDL1.2 (on X11 at least) they were the X11_KeySym & 0xFF, + * if (X11_KeySym >> 8)) was either 0 to 8 or 0x0A or 0x0C or 0x0E + * So map all those used UCS-4 codes to the corresponding SDLK12_WORLD_* codes + * Note that the Latin-1 range (keysym20 <= 255) is already handled at the top of this function + * Luckily X11's keysymdef.h lists both the values of the constants and their UCS4-value, like + * #define XK_Aogonek 0x01a1 / * U+0104 LATIN CAPITAL LETTER A WITH OGONEK * / + * So I'm using that as a reference for our mappings, which only use + * the lowest byte of the XK_* value, because of X11_KeySym & 0xFF in SDL1.2 + * + * case UTC4_code: return (SDL12Key)lowest_byte_of_corresponding_X11_KeySym; */ + + /* Latin-2 */ + case 0x0104: return (SDL12Key)0xa1; + case 0x02D8: return (SDL12Key)0xa2; + case 0x0141: return (SDL12Key)0xa3; + case 0x013D: return (SDL12Key)0xa5; + case 0x015A: return (SDL12Key)0xa6; + case 0x0160: return (SDL12Key)0xa9; + case 0x015E: return (SDL12Key)0xaa; + case 0x0164: return (SDL12Key)0xab; + case 0x0179: return (SDL12Key)0xac; + case 0x017D: return (SDL12Key)0xae; + case 0x017B: return (SDL12Key)0xaf; + case 0x0105: return (SDL12Key)0xb1; + case 0x02DB: return (SDL12Key)0xb2; + case 0x0142: return (SDL12Key)0xb3; + case 0x013E: return (SDL12Key)0xb5; + case 0x015B: return (SDL12Key)0xb6; + case 0x02C7: return (SDL12Key)0xb7; + case 0x0161: return (SDL12Key)0xb9; + case 0x015F: return (SDL12Key)0xba; + case 0x0165: return (SDL12Key)0xbb; + case 0x017A: return (SDL12Key)0xbc; + case 0x02DD: return (SDL12Key)0xbd; + case 0x017E: return (SDL12Key)0xbe; + case 0x017C: return (SDL12Key)0xbf; + case 0x0154: return (SDL12Key)0xc0; + case 0x0102: return (SDL12Key)0xc3; + case 0x0139: return (SDL12Key)0xc5; + case 0x0106: return (SDL12Key)0xc6; + case 0x010C: return (SDL12Key)0xc8; + case 0x0118: return (SDL12Key)0xca; + case 0x011A: return (SDL12Key)0xcc; + case 0x010E: return (SDL12Key)0xcf; + case 0x0110: return (SDL12Key)0xd0; + case 0x0143: return (SDL12Key)0xd1; + case 0x0147: return (SDL12Key)0xd2; + case 0x0150: return (SDL12Key)0xd5; + case 0x0158: return (SDL12Key)0xd8; + case 0x016E: return (SDL12Key)0xd9; + case 0x0170: return (SDL12Key)0xdb; + case 0x0162: return (SDL12Key)0xde; + case 0x0155: return (SDL12Key)0xe0; + case 0x0103: return (SDL12Key)0xe3; + case 0x013A: return (SDL12Key)0xe5; + case 0x0107: return (SDL12Key)0xe6; + case 0x010D: return (SDL12Key)0xe8; + case 0x0119: return (SDL12Key)0xea; + case 0x011B: return (SDL12Key)0xec; + case 0x010F: return (SDL12Key)0xef; + case 0x0111: return (SDL12Key)0xf0; + case 0x0144: return (SDL12Key)0xf1; + case 0x0148: return (SDL12Key)0xf2; + case 0x0151: return (SDL12Key)0xf5; + case 0x0159: return (SDL12Key)0xf8; + case 0x016F: return (SDL12Key)0xf9; + case 0x0171: return (SDL12Key)0xfb; + case 0x0163: return (SDL12Key)0xfe; + case 0x02D9: return (SDL12Key)0xff; + /* Latin-3 */ + case 0x0126: return (SDL12Key)0xa1; + case 0x0124: return (SDL12Key)0xa6; + case 0x0130: return (SDL12Key)0xa9; + case 0x011E: return (SDL12Key)0xab; + case 0x0134: return (SDL12Key)0xac; + case 0x0127: return (SDL12Key)0xb1; + case 0x0125: return (SDL12Key)0xb6; + case 0x0131: return (SDL12Key)0xb9; + case 0x011F: return (SDL12Key)0xbb; + case 0x0135: return (SDL12Key)0xbc; + case 0x010A: return (SDL12Key)0xc5; + case 0x0108: return (SDL12Key)0xc6; + case 0x0120: return (SDL12Key)0xd5; + case 0x011C: return (SDL12Key)0xd8; + case 0x016C: return (SDL12Key)0xdd; + case 0x015C: return (SDL12Key)0xde; + case 0x010B: return (SDL12Key)0xe5; + case 0x0109: return (SDL12Key)0xe6; + case 0x0121: return (SDL12Key)0xf5; + case 0x011D: return (SDL12Key)0xf8; + case 0x016D: return (SDL12Key)0xfd; + case 0x015D: return (SDL12Key)0xfe; + /* Latin 4 */ + case 0x0138: return (SDL12Key)0xa2; + case 0x0156: return (SDL12Key)0xa3; + case 0x0128: return (SDL12Key)0xa5; + case 0x013B: return (SDL12Key)0xa6; + case 0x0112: return (SDL12Key)0xaa; + case 0x0122: return (SDL12Key)0xab; + case 0x0166: return (SDL12Key)0xac; + case 0x0157: return (SDL12Key)0xb3; + case 0x0129: return (SDL12Key)0xb5; + case 0x013C: return (SDL12Key)0xb6; + case 0x0113: return (SDL12Key)0xba; + case 0x0123: return (SDL12Key)0xbb; + case 0x0167: return (SDL12Key)0xbc; + case 0x014A: return (SDL12Key)0xbd; + case 0x014B: return (SDL12Key)0xbf; + case 0x0100: return (SDL12Key)0xc0; + case 0x012E: return (SDL12Key)0xc7; + case 0x0116: return (SDL12Key)0xcc; + case 0x012A: return (SDL12Key)0xcf; + case 0x0145: return (SDL12Key)0xd1; + case 0x014C: return (SDL12Key)0xd2; + case 0x0136: return (SDL12Key)0xd3; + case 0x0172: return (SDL12Key)0xd9; + case 0x0168: return (SDL12Key)0xdd; + case 0x016A: return (SDL12Key)0xde; + case 0x0101: return (SDL12Key)0xe0; + case 0x012F: return (SDL12Key)0xe7; + case 0x0117: return (SDL12Key)0xec; + case 0x012B: return (SDL12Key)0xef; + case 0x0146: return (SDL12Key)0xf1; + case 0x014D: return (SDL12Key)0xf2; + case 0x0137: return (SDL12Key)0xf3; + case 0x0173: return (SDL12Key)0xf9; + case 0x0169: return (SDL12Key)0xfd; + case 0x016B: return (SDL12Key)0xfe; + /* Katakana */ + case 0x203E: return (SDL12Key)0x7e; + case 0x3002: return (SDL12Key)0xa1; + case 0x300C: return (SDL12Key)0xa2; + case 0x300D: return (SDL12Key)0xa3; + case 0x3001: return (SDL12Key)0xa4; + case 0x30FB: return (SDL12Key)0xa5; + case 0x30F2: return (SDL12Key)0xa6; + case 0x30A1: return (SDL12Key)0xa7; + case 0x30A3: return (SDL12Key)0xa8; + case 0x30A5: return (SDL12Key)0xa9; + case 0x30A7: return (SDL12Key)0xaa; + case 0x30A9: return (SDL12Key)0xab; + case 0x30E3: return (SDL12Key)0xac; + case 0x30E5: return (SDL12Key)0xad; + case 0x30E7: return (SDL12Key)0xae; + case 0x30C3: return (SDL12Key)0xaf; + case 0x30FC: return (SDL12Key)0xb0; + case 0x30A2: return (SDL12Key)0xb1; + case 0x30A4: return (SDL12Key)0xb2; + case 0x30A6: return (SDL12Key)0xb3; + case 0x30A8: return (SDL12Key)0xb4; + case 0x30AA: return (SDL12Key)0xb5; + case 0x30AB: return (SDL12Key)0xb6; + case 0x30AD: return (SDL12Key)0xb7; + case 0x30AF: return (SDL12Key)0xb8; + case 0x30B1: return (SDL12Key)0xb9; + case 0x30B3: return (SDL12Key)0xba; + case 0x30B5: return (SDL12Key)0xbb; + case 0x30B7: return (SDL12Key)0xbc; + case 0x30B9: return (SDL12Key)0xbd; + case 0x30BB: return (SDL12Key)0xbe; + case 0x30BD: return (SDL12Key)0xbf; + case 0x30BF: return (SDL12Key)0xc0; + case 0x30C1: return (SDL12Key)0xc1; + case 0x30C4: return (SDL12Key)0xc2; + case 0x30C6: return (SDL12Key)0xc3; + case 0x30C8: return (SDL12Key)0xc4; + case 0x30CA: return (SDL12Key)0xc5; + case 0x30CB: return (SDL12Key)0xc6; + case 0x30CC: return (SDL12Key)0xc7; + case 0x30CD: return (SDL12Key)0xc8; + case 0x30CE: return (SDL12Key)0xc9; + case 0x30CF: return (SDL12Key)0xca; + case 0x30D2: return (SDL12Key)0xcb; + case 0x30D5: return (SDL12Key)0xcc; + case 0x30D8: return (SDL12Key)0xcd; + case 0x30DB: return (SDL12Key)0xce; + case 0x30DE: return (SDL12Key)0xcf; + case 0x30DF: return (SDL12Key)0xd0; + case 0x30E0: return (SDL12Key)0xd1; + case 0x30E1: return (SDL12Key)0xd2; + case 0x30E2: return (SDL12Key)0xd3; + case 0x30E4: return (SDL12Key)0xd4; + case 0x30E6: return (SDL12Key)0xd5; + case 0x30E8: return (SDL12Key)0xd6; + case 0x30E9: return (SDL12Key)0xd7; + case 0x30EA: return (SDL12Key)0xd8; + case 0x30EB: return (SDL12Key)0xd9; + case 0x30EC: return (SDL12Key)0xda; + case 0x30ED: return (SDL12Key)0xdb; + case 0x30EF: return (SDL12Key)0xdc; + case 0x30F3: return (SDL12Key)0xdd; + case 0x309B: return (SDL12Key)0xde; + case 0x309C: return (SDL12Key)0xdf; + /* Arabic */ + case 0x060C: return (SDL12Key)0xac; + case 0x061B: return (SDL12Key)0xbb; + case 0x061F: return (SDL12Key)0xbf; + case 0x0621: return (SDL12Key)0xc1; + case 0x0622: return (SDL12Key)0xc2; + case 0x0623: return (SDL12Key)0xc3; + case 0x0624: return (SDL12Key)0xc4; + case 0x0625: return (SDL12Key)0xc5; + case 0x0626: return (SDL12Key)0xc6; + case 0x0627: return (SDL12Key)0xc7; + case 0x0628: return (SDL12Key)0xc8; + case 0x0629: return (SDL12Key)0xc9; + case 0x062A: return (SDL12Key)0xca; + case 0x062B: return (SDL12Key)0xcb; + case 0x062C: return (SDL12Key)0xcc; + case 0x062D: return (SDL12Key)0xcd; + case 0x062E: return (SDL12Key)0xce; + case 0x062F: return (SDL12Key)0xcf; + case 0x0630: return (SDL12Key)0xd0; + case 0x0631: return (SDL12Key)0xd1; + case 0x0632: return (SDL12Key)0xd2; + case 0x0633: return (SDL12Key)0xd3; + case 0x0634: return (SDL12Key)0xd4; + case 0x0635: return (SDL12Key)0xd5; + case 0x0636: return (SDL12Key)0xd6; + case 0x0637: return (SDL12Key)0xd7; + case 0x0638: return (SDL12Key)0xd8; + case 0x0639: return (SDL12Key)0xd9; + case 0x063A: return (SDL12Key)0xda; + case 0x0640: return (SDL12Key)0xe0; + case 0x0641: return (SDL12Key)0xe1; + case 0x0642: return (SDL12Key)0xe2; + case 0x0643: return (SDL12Key)0xe3; + case 0x0644: return (SDL12Key)0xe4; + case 0x0645: return (SDL12Key)0xe5; + case 0x0646: return (SDL12Key)0xe6; + case 0x0647: return (SDL12Key)0xe7; + case 0x0648: return (SDL12Key)0xe8; + case 0x0649: return (SDL12Key)0xe9; + case 0x064A: return (SDL12Key)0xea; + case 0x064B: return (SDL12Key)0xeb; + case 0x064C: return (SDL12Key)0xec; + case 0x064D: return (SDL12Key)0xed; + case 0x064E: return (SDL12Key)0xee; + case 0x064F: return (SDL12Key)0xef; + case 0x0650: return (SDL12Key)0xf0; + case 0x0651: return (SDL12Key)0xf1; + case 0x0652: return (SDL12Key)0xf2; + /* Cyrillic */ + case 0x0452: return (SDL12Key)0xa1; + case 0x0453: return (SDL12Key)0xa2; + case 0x0451: return (SDL12Key)0xa3; + case 0x0454: return (SDL12Key)0xa4; + case 0x0455: return (SDL12Key)0xa5; + case 0x0456: return (SDL12Key)0xa6; + case 0x0457: return (SDL12Key)0xa7; + case 0x0458: return (SDL12Key)0xa8; + case 0x0459: return (SDL12Key)0xa9; + case 0x045A: return (SDL12Key)0xaa; + case 0x045B: return (SDL12Key)0xab; + case 0x045C: return (SDL12Key)0xac; + case 0x0491: return (SDL12Key)0xad; + case 0x045E: return (SDL12Key)0xae; + case 0x045F: return (SDL12Key)0xaf; + case 0x2116: return (SDL12Key)0xb0; + case 0x0402: return (SDL12Key)0xb1; + case 0x0403: return (SDL12Key)0xb2; + case 0x0401: return (SDL12Key)0xb3; + case 0x0404: return (SDL12Key)0xb4; + case 0x0405: return (SDL12Key)0xb5; + case 0x0406: return (SDL12Key)0xb6; + case 0x0407: return (SDL12Key)0xb7; + case 0x0408: return (SDL12Key)0xb8; + case 0x0409: return (SDL12Key)0xb9; + case 0x040A: return (SDL12Key)0xba; + case 0x040B: return (SDL12Key)0xbb; + case 0x040C: return (SDL12Key)0xbc; + case 0x0490: return (SDL12Key)0xbd; + case 0x040E: return (SDL12Key)0xbe; + case 0x040F: return (SDL12Key)0xbf; + case 0x044E: return (SDL12Key)0xc0; + case 0x0430: return (SDL12Key)0xc1; + case 0x0431: return (SDL12Key)0xc2; + case 0x0446: return (SDL12Key)0xc3; + case 0x0434: return (SDL12Key)0xc4; + case 0x0435: return (SDL12Key)0xc5; + case 0x0444: return (SDL12Key)0xc6; + case 0x0433: return (SDL12Key)0xc7; + case 0x0445: return (SDL12Key)0xc8; + case 0x0438: return (SDL12Key)0xc9; + case 0x0439: return (SDL12Key)0xca; + case 0x043A: return (SDL12Key)0xcb; + case 0x043B: return (SDL12Key)0xcc; + case 0x043C: return (SDL12Key)0xcd; + case 0x043D: return (SDL12Key)0xce; + case 0x043E: return (SDL12Key)0xcf; + case 0x043F: return (SDL12Key)0xd0; + case 0x044F: return (SDL12Key)0xd1; + case 0x0440: return (SDL12Key)0xd2; + case 0x0441: return (SDL12Key)0xd3; + case 0x0442: return (SDL12Key)0xd4; + case 0x0443: return (SDL12Key)0xd5; + case 0x0436: return (SDL12Key)0xd6; + case 0x0432: return (SDL12Key)0xd7; + case 0x044C: return (SDL12Key)0xd8; + case 0x044B: return (SDL12Key)0xd9; + case 0x0437: return (SDL12Key)0xda; + case 0x0448: return (SDL12Key)0xdb; + case 0x044D: return (SDL12Key)0xdc; + case 0x0449: return (SDL12Key)0xdd; + case 0x0447: return (SDL12Key)0xde; + case 0x044A: return (SDL12Key)0xdf; + case 0x042E: return (SDL12Key)0xe0; + case 0x0410: return (SDL12Key)0xe1; + case 0x0411: return (SDL12Key)0xe2; + case 0x0426: return (SDL12Key)0xe3; + case 0x0414: return (SDL12Key)0xe4; + case 0x0415: return (SDL12Key)0xe5; + case 0x0424: return (SDL12Key)0xe6; + case 0x0413: return (SDL12Key)0xe7; + case 0x0425: return (SDL12Key)0xe8; + case 0x0418: return (SDL12Key)0xe9; + case 0x0419: return (SDL12Key)0xea; + case 0x041A: return (SDL12Key)0xeb; + case 0x041B: return (SDL12Key)0xec; + case 0x041C: return (SDL12Key)0xed; + case 0x041D: return (SDL12Key)0xee; + case 0x041E: return (SDL12Key)0xef; + case 0x041F: return (SDL12Key)0xf0; + case 0x042F: return (SDL12Key)0xf1; + case 0x0420: return (SDL12Key)0xf2; + case 0x0421: return (SDL12Key)0xf3; + case 0x0422: return (SDL12Key)0xf4; + case 0x0423: return (SDL12Key)0xf5; + case 0x0416: return (SDL12Key)0xf6; + case 0x0412: return (SDL12Key)0xf7; + case 0x042C: return (SDL12Key)0xf8; + case 0x042B: return (SDL12Key)0xf9; + case 0x0417: return (SDL12Key)0xfa; + case 0x0428: return (SDL12Key)0xfb; + case 0x042D: return (SDL12Key)0xfc; + case 0x0429: return (SDL12Key)0xfd; + case 0x0427: return (SDL12Key)0xfe; + case 0x042A: return (SDL12Key)0xff; + /* Greek */ + case 0x0386: return (SDL12Key)0xa1; + case 0x0388: return (SDL12Key)0xa2; + case 0x0389: return (SDL12Key)0xa3; + case 0x038A: return (SDL12Key)0xa4; + case 0x03AA: return (SDL12Key)0xa5; + case 0x038C: return (SDL12Key)0xa7; + case 0x038E: return (SDL12Key)0xa8; + case 0x03AB: return (SDL12Key)0xa9; + case 0x038F: return (SDL12Key)0xab; + case 0x0385: return (SDL12Key)0xae; + case 0x2015: return (SDL12Key)0xaf; + case 0x03AC: return (SDL12Key)0xb1; + case 0x03AD: return (SDL12Key)0xb2; + case 0x03AE: return (SDL12Key)0xb3; + case 0x03AF: return (SDL12Key)0xb4; + case 0x03CA: return (SDL12Key)0xb5; + case 0x0390: return (SDL12Key)0xb6; + case 0x03CC: return (SDL12Key)0xb7; + case 0x03CD: return (SDL12Key)0xb8; + case 0x03CB: return (SDL12Key)0xb9; + case 0x03B0: return (SDL12Key)0xba; + case 0x03CE: return (SDL12Key)0xbb; + case 0x0391: return (SDL12Key)0xc1; + case 0x0392: return (SDL12Key)0xc2; + case 0x0393: return (SDL12Key)0xc3; + case 0x0394: return (SDL12Key)0xc4; + case 0x0395: return (SDL12Key)0xc5; + case 0x0396: return (SDL12Key)0xc6; + case 0x0397: return (SDL12Key)0xc7; + case 0x0398: return (SDL12Key)0xc8; + case 0x0399: return (SDL12Key)0xc9; + case 0x039A: return (SDL12Key)0xca; + case 0x039B: return (SDL12Key)0xcb; + case 0x039C: return (SDL12Key)0xcc; + case 0x039D: return (SDL12Key)0xcd; + case 0x039E: return (SDL12Key)0xce; + case 0x039F: return (SDL12Key)0xcf; + case 0x03A0: return (SDL12Key)0xd0; + case 0x03A1: return (SDL12Key)0xd1; + case 0x03A3: return (SDL12Key)0xd2; + case 0x03A4: return (SDL12Key)0xd4; + case 0x03A5: return (SDL12Key)0xd5; + case 0x03A6: return (SDL12Key)0xd6; + case 0x03A7: return (SDL12Key)0xd7; + case 0x03A8: return (SDL12Key)0xd8; + case 0x03A9: return (SDL12Key)0xd9; + case 0x03B1: return (SDL12Key)0xe1; + case 0x03B2: return (SDL12Key)0xe2; + case 0x03B3: return (SDL12Key)0xe3; + case 0x03B4: return (SDL12Key)0xe4; + case 0x03B5: return (SDL12Key)0xe5; + case 0x03B6: return (SDL12Key)0xe6; + case 0x03B7: return (SDL12Key)0xe7; + case 0x03B8: return (SDL12Key)0xe8; + case 0x03B9: return (SDL12Key)0xe9; + case 0x03BA: return (SDL12Key)0xea; + case 0x03BB: return (SDL12Key)0xeb; + case 0x03BC: return (SDL12Key)0xec; + case 0x03BD: return (SDL12Key)0xed; + case 0x03BE: return (SDL12Key)0xee; + case 0x03BF: return (SDL12Key)0xef; + case 0x03C0: return (SDL12Key)0xf0; + case 0x03C1: return (SDL12Key)0xf1; + case 0x03C3: return (SDL12Key)0xf2; + case 0x03C2: return (SDL12Key)0xf3; + case 0x03C4: return (SDL12Key)0xf4; + case 0x03C5: return (SDL12Key)0xf5; + case 0x03C6: return (SDL12Key)0xf6; + case 0x03C7: return (SDL12Key)0xf7; + case 0x03C8: return (SDL12Key)0xf8; + case 0x03C9: return (SDL12Key)0xf9; + /* Technical */ + case 0x23B7: return (SDL12Key)0xa1; + case 0x250C: return (SDL12Key)0xa2; + case 0x2500: return (SDL12Key)0xa3; + case 0x2320: return (SDL12Key)0xa4; + case 0x2321: return (SDL12Key)0xa5; + case 0x2502: return (SDL12Key)0xa6; + case 0x23A1: return (SDL12Key)0xa7; + case 0x23A3: return (SDL12Key)0xa8; + case 0x23A4: return (SDL12Key)0xa9; + case 0x23A6: return (SDL12Key)0xaa; + case 0x239B: return (SDL12Key)0xab; + case 0x239D: return (SDL12Key)0xac; + case 0x239E: return (SDL12Key)0xad; + case 0x23A0: return (SDL12Key)0xae; + case 0x23A8: return (SDL12Key)0xaf; + case 0x23AC: return (SDL12Key)0xb0; + case 0x2264: return (SDL12Key)0xbc; + case 0x2260: return (SDL12Key)0xbd; + case 0x2265: return (SDL12Key)0xbe; + case 0x222B: return (SDL12Key)0xbf; + case 0x2234: return (SDL12Key)0xc0; + case 0x221D: return (SDL12Key)0xc1; + case 0x221E: return (SDL12Key)0xc2; + case 0x2207: return (SDL12Key)0xc5; + case 0x223C: return (SDL12Key)0xc8; + case 0x2243: return (SDL12Key)0xc9; + case 0x21D4: return (SDL12Key)0xcd; + case 0x21D2: return (SDL12Key)0xce; + case 0x2261: return (SDL12Key)0xcf; + case 0x221A: return (SDL12Key)0xd6; + case 0x2282: return (SDL12Key)0xda; + case 0x2283: return (SDL12Key)0xdb; + case 0x2229: return (SDL12Key)0xdc; + case 0x222A: return (SDL12Key)0xdd; + case 0x2227: return (SDL12Key)0xde; + case 0x2228: return (SDL12Key)0xdf; + case 0x2202: return (SDL12Key)0xef; + case 0x0192: return (SDL12Key)0xf6; + case 0x2190: return (SDL12Key)0xfb; + case 0x2191: return (SDL12Key)0xfc; + case 0x2192: return (SDL12Key)0xfd; + case 0x2193: return (SDL12Key)0xfe; + /* Publishing */ + case 0x2003: return (SDL12Key)0xa1; + case 0x2002: return (SDL12Key)0xa2; + case 0x2004: return (SDL12Key)0xa3; + case 0x2005: return (SDL12Key)0xa4; + case 0x2007: return (SDL12Key)0xa5; + case 0x2008: return (SDL12Key)0xa6; + case 0x2009: return (SDL12Key)0xa7; + case 0x200A: return (SDL12Key)0xa8; + case 0x2014: return (SDL12Key)0xa9; + case 0x2013: return (SDL12Key)0xaa; + case 0x2423: return (SDL12Key)0xac; + case 0x2026: return (SDL12Key)0xae; + case 0x2025: return (SDL12Key)0xaf; + case 0x2153: return (SDL12Key)0xb0; + case 0x2154: return (SDL12Key)0xb1; + case 0x2155: return (SDL12Key)0xb2; + case 0x2156: return (SDL12Key)0xb3; + case 0x2157: return (SDL12Key)0xb4; + case 0x2158: return (SDL12Key)0xb5; + case 0x2159: return (SDL12Key)0xb6; + case 0x215A: return (SDL12Key)0xb7; + case 0x2105: return (SDL12Key)0xb8; + case 0x2012: return (SDL12Key)0xbb; + case 0x27E8: return (SDL12Key)0xbc; + case 0x002E: return (SDL12Key)0xbd; + case 0x27E9: return (SDL12Key)0xbe; + case 0x215B: return (SDL12Key)0xc3; + case 0x215C: return (SDL12Key)0xc4; + case 0x215D: return (SDL12Key)0xc5; + case 0x215E: return (SDL12Key)0xc6; + case 0x2122: return (SDL12Key)0xc9; + case 0x2613: return (SDL12Key)0xca; + case 0x25C1: return (SDL12Key)0xcc; + case 0x25B7: return (SDL12Key)0xcd; + case 0x25CB: return (SDL12Key)0xce; + case 0x25AF: return (SDL12Key)0xcf; + case 0x2018: return (SDL12Key)0xd0; + case 0x2019: return (SDL12Key)0xd1; + case 0x201C: return (SDL12Key)0xd2; + case 0x201D: return (SDL12Key)0xd3; + case 0x211E: return (SDL12Key)0xd4; + case 0x2030: return (SDL12Key)0xd5; + case 0x2032: return (SDL12Key)0xd6; + case 0x2033: return (SDL12Key)0xd7; + case 0x271D: return (SDL12Key)0xd9; + case 0x25AC: return (SDL12Key)0xdb; + case 0x25C0: return (SDL12Key)0xdc; + case 0x25B6: return (SDL12Key)0xdd; + case 0x25CF: return (SDL12Key)0xde; + case 0x25AE: return (SDL12Key)0xdf; + case 0x25E6: return (SDL12Key)0xe0; + case 0x25AB: return (SDL12Key)0xe1; + case 0x25AD: return (SDL12Key)0xe2; + case 0x25B3: return (SDL12Key)0xe3; + case 0x25BD: return (SDL12Key)0xe4; + case 0x2606: return (SDL12Key)0xe5; + case 0x2022: return (SDL12Key)0xe6; + case 0x25AA: return (SDL12Key)0xe7; + case 0x25B2: return (SDL12Key)0xe8; + case 0x25BC: return (SDL12Key)0xe9; + case 0x261C: return (SDL12Key)0xea; + case 0x261E: return (SDL12Key)0xeb; + case 0x2663: return (SDL12Key)0xec; + case 0x2666: return (SDL12Key)0xed; + case 0x2665: return (SDL12Key)0xee; + case 0x2720: return (SDL12Key)0xf0; + case 0x2020: return (SDL12Key)0xf1; + case 0x2021: return (SDL12Key)0xf2; + case 0x2713: return (SDL12Key)0xf3; + case 0x2717: return (SDL12Key)0xf4; + case 0x266F: return (SDL12Key)0xf5; + case 0x266D: return (SDL12Key)0xf6; + case 0x2642: return (SDL12Key)0xf7; + case 0x2640: return (SDL12Key)0xf8; + case 0x260E: return (SDL12Key)0xf9; + case 0x2315: return (SDL12Key)0xfa; + case 0x2117: return (SDL12Key)0xfb; + case 0x2038: return (SDL12Key)0xfc; + case 0x201A: return (SDL12Key)0xfd; + case 0x201E: return (SDL12Key)0xfe; + /* Hebrew */ + case 0x2017: return (SDL12Key)0xdf; + case 0x05D0: return (SDL12Key)0xe0; + case 0x05D1: return (SDL12Key)0xe1; + case 0x05D2: return (SDL12Key)0xe2; + case 0x05D3: return (SDL12Key)0xe3; + case 0x05D4: return (SDL12Key)0xe4; + case 0x05D5: return (SDL12Key)0xe5; + case 0x05D6: return (SDL12Key)0xe6; + case 0x05D7: return (SDL12Key)0xe7; + case 0x05D8: return (SDL12Key)0xe8; + case 0x05D9: return (SDL12Key)0xe9; + case 0x05DA: return (SDL12Key)0xea; + case 0x05DB: return (SDL12Key)0xeb; + case 0x05DC: return (SDL12Key)0xec; + case 0x05DD: return (SDL12Key)0xed; + case 0x05DE: return (SDL12Key)0xee; + case 0x05DF: return (SDL12Key)0xef; + case 0x05E0: return (SDL12Key)0xf0; + case 0x05E1: return (SDL12Key)0xf1; + case 0x05E2: return (SDL12Key)0xf2; + case 0x05E3: return (SDL12Key)0xf3; + case 0x05E4: return (SDL12Key)0xf4; + case 0x05E5: return (SDL12Key)0xf5; + case 0x05E6: return (SDL12Key)0xf6; + case 0x05E7: return (SDL12Key)0xf7; + case 0x05E8: return (SDL12Key)0xf8; + case 0x05E9: return (SDL12Key)0xf9; + case 0x05EA: return (SDL12Key)0xfa; + /* Thai */ + case 0x0E01: return (SDL12Key)0xa1; + case 0x0E02: return (SDL12Key)0xa2; + case 0x0E03: return (SDL12Key)0xa3; + case 0x0E04: return (SDL12Key)0xa4; + case 0x0E05: return (SDL12Key)0xa5; + case 0x0E06: return (SDL12Key)0xa6; + case 0x0E07: return (SDL12Key)0xa7; + case 0x0E08: return (SDL12Key)0xa8; + case 0x0E09: return (SDL12Key)0xa9; + case 0x0E0A: return (SDL12Key)0xaa; + case 0x0E0B: return (SDL12Key)0xab; + case 0x0E0C: return (SDL12Key)0xac; + case 0x0E0D: return (SDL12Key)0xad; + case 0x0E0E: return (SDL12Key)0xae; + case 0x0E0F: return (SDL12Key)0xaf; + case 0x0E10: return (SDL12Key)0xb0; + case 0x0E11: return (SDL12Key)0xb1; + case 0x0E12: return (SDL12Key)0xb2; + case 0x0E13: return (SDL12Key)0xb3; + case 0x0E14: return (SDL12Key)0xb4; + case 0x0E15: return (SDL12Key)0xb5; + case 0x0E16: return (SDL12Key)0xb6; + case 0x0E17: return (SDL12Key)0xb7; + case 0x0E18: return (SDL12Key)0xb8; + case 0x0E19: return (SDL12Key)0xb9; + case 0x0E1A: return (SDL12Key)0xba; + case 0x0E1B: return (SDL12Key)0xbb; + case 0x0E1C: return (SDL12Key)0xbc; + case 0x0E1D: return (SDL12Key)0xbd; + case 0x0E1E: return (SDL12Key)0xbe; + case 0x0E1F: return (SDL12Key)0xbf; + case 0x0E20: return (SDL12Key)0xc0; + case 0x0E21: return (SDL12Key)0xc1; + case 0x0E22: return (SDL12Key)0xc2; + case 0x0E23: return (SDL12Key)0xc3; + case 0x0E24: return (SDL12Key)0xc4; + case 0x0E25: return (SDL12Key)0xc5; + case 0x0E26: return (SDL12Key)0xc6; + case 0x0E27: return (SDL12Key)0xc7; + case 0x0E28: return (SDL12Key)0xc8; + case 0x0E29: return (SDL12Key)0xc9; + case 0x0E2A: return (SDL12Key)0xca; + case 0x0E2B: return (SDL12Key)0xcb; + case 0x0E2C: return (SDL12Key)0xcc; + case 0x0E2D: return (SDL12Key)0xcd; + case 0x0E2E: return (SDL12Key)0xce; + case 0x0E2F: return (SDL12Key)0xcf; + case 0x0E30: return (SDL12Key)0xd0; + case 0x0E31: return (SDL12Key)0xd1; + case 0x0E32: return (SDL12Key)0xd2; + case 0x0E33: return (SDL12Key)0xd3; + case 0x0E34: return (SDL12Key)0xd4; + case 0x0E35: return (SDL12Key)0xd5; + case 0x0E36: return (SDL12Key)0xd6; + case 0x0E37: return (SDL12Key)0xd7; + case 0x0E38: return (SDL12Key)0xd8; + case 0x0E39: return (SDL12Key)0xd9; + case 0x0E3A: return (SDL12Key)0xda; + case 0x0E3F: return (SDL12Key)0xdf; + case 0x0E40: return (SDL12Key)0xe0; + case 0x0E41: return (SDL12Key)0xe1; + case 0x0E42: return (SDL12Key)0xe2; + case 0x0E43: return (SDL12Key)0xe3; + case 0x0E44: return (SDL12Key)0xe4; + case 0x0E45: return (SDL12Key)0xe5; + case 0x0E46: return (SDL12Key)0xe6; + case 0x0E47: return (SDL12Key)0xe7; + case 0x0E48: return (SDL12Key)0xe8; + case 0x0E49: return (SDL12Key)0xe9; + case 0x0E4A: return (SDL12Key)0xea; + case 0x0E4B: return (SDL12Key)0xeb; + case 0x0E4C: return (SDL12Key)0xec; + case 0x0E4D: return (SDL12Key)0xed; + case 0x0E50: return (SDL12Key)0xf0; + case 0x0E51: return (SDL12Key)0xf1; + case 0x0E52: return (SDL12Key)0xf2; + case 0x0E53: return (SDL12Key)0xf3; + case 0x0E54: return (SDL12Key)0xf4; + case 0x0E55: return (SDL12Key)0xf5; + case 0x0E56: return (SDL12Key)0xf6; + case 0x0E57: return (SDL12Key)0xf7; + case 0x0E58: return (SDL12Key)0xf8; + case 0x0E59: return (SDL12Key)0xf9; + /* end of SDLK_WORLD_ keys based on Latin-* or similar High-ASCII charsets + * and the low byte of their corresponding X11 XK_* KeySyms */ default: break; } FIXME("nothing maps to SDLK12_COMPOSE, SDLK12_BREAK, or SDLK12_EURO ...?"); - FIXME("map some of the SDLK12_WORLD keys"); return SDLK12_UNKNOWN; } static SDL12Key From 50f2f2d23789b07511ca2fd40724347c07aa872e Mon Sep 17 00:00:00 2001 From: Daniel Gibson Date: Mon, 8 Nov 2021 00:33:30 +0100 Subject: [PATCH 153/606] checkkeys test: Improve printing of Unicode-Chars MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .. at least on platforms that use UTF-8, like modern Linux (Windows should work as well as before). Also unified the output to print sth like "'Ä' (0x00C4)", i.e. both the actual char and the unicode constant, on all platforms. --- test/checkkeys.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/test/checkkeys.c b/test/checkkeys.c index b37da9305..2df1d90ed 100644 --- a/test/checkkeys.c +++ b/test/checkkeys.c @@ -68,13 +68,19 @@ static void PrintKey(SDL_keysym *sym, int pressed) printf(" (^%c)", sym->unicode+'@'); } else { #ifdef UNICODE - printf(" (%c)", sym->unicode); -#else + printf(" '%c' (0x%.4X)", sym->unicode, (int)sym->unicode); +#elif defined(_WIN32) /* This is a Latin-1 program, so only show 8-bits */ if ( !(sym->unicode & 0xFF00) ) - printf(" (%c)", sym->unicode); + printf(" '%c' (0x%.4X)", sym->unicode, (int)sym->unicode); else - printf(" (0x%X)", sym->unicode); + printf(" (0x%.4X)", (int)sym->unicode); +#else /* other platforms than Windows hopefully use UTF-8 for 8bit chars */ + Uint32 utf32str[2] = { sym->unicode, 0 }; + const char* utf32type = (SDL_BYTEORDER == SDL_LIL_ENDIAN) ? "UTF-32LE" : "UTF-32BE"; + char* utf8str = SDL_iconv_string("UTF-8", utf32type, (const char*)utf32str, 2*4); + printf(" '%s' (0x%.4X)", utf8str, (int)sym->unicode); + SDL_free(utf8str); #endif } } From a10d6b68efdc67cfb303536ca0bb42e4bfdff665 Mon Sep 17 00:00:00 2001 From: Daniel Gibson Date: Mon, 8 Nov 2021 00:58:19 +0100 Subject: [PATCH 154/606] Remove duplicated semicolon and typo in SDL12_compat.c --- src/SDL12_compat.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index fde1a4de8..a550b29d1 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -2654,7 +2654,7 @@ Keysym20to12(const SDL_Keycode keysym20) CASEKEYSYM20TO12(LALT); CASEKEYSYM20TO12(MODE); CASEKEYSYM20TO12(HELP); - CASEKEYSYM20TO12(SYSREQ);; + CASEKEYSYM20TO12(SYSREQ); CASEKEYSYM20TO12(MENU); CASEKEYSYM20TO12(POWER); CASEKEYSYM20TO12(UNDO); @@ -2671,7 +2671,7 @@ Keysym20to12(const SDL_Keycode keysym20) * So I'm using that as a reference for our mappings, which only use * the lowest byte of the XK_* value, because of X11_KeySym & 0xFF in SDL1.2 * - * case UTC4_code: return (SDL12Key)lowest_byte_of_corresponding_X11_KeySym; */ + * case UCS4_code: return (SDL12Key)lowest_byte_of_corresponding_X11_KeySym; */ /* Latin-2 */ case 0x0104: return (SDL12Key)0xa1; From c4f94494d7bff49c57193b2a78b86fc197dd5b11 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Thu, 11 Nov 2021 23:51:50 +0300 Subject: [PATCH 155/606] minor update to standalone makefiles. --- src/Makefile.darwin | 7 ++++--- src/Makefile.linux | 12 ++++++------ src/Makefile.mingw | 8 ++++---- src/Makefile.vc | 1 + 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/Makefile.darwin b/src/Makefile.darwin index ddd868772..77bef81de 100644 --- a/src/Makefile.darwin +++ b/src/Makefile.darwin @@ -5,9 +5,9 @@ INCLUDES = -Iinclude ifeq ($(CROSS),) -CC=gcc +CC = gcc else -CC=$(CROSS)-gcc +CC = $(CROSS)-gcc endif LD = $(CC) @@ -34,7 +34,8 @@ all: $(DYLIB) $(DYLIB): $(OBJ) $(LD) -o $@ $(LDFLAGS) $(OBJ) $(LDLIBS) - ln -s $(DYLIB) libSDL.dylib + ln -sf $(DYLIB) libSDL.dylib + .c.o: $(CC) $(CFLAGS) $(CPPFLAGS) $(INCLUDES) -o $@ -c $< .m.o: diff --git a/src/Makefile.linux b/src/Makefile.linux index 8a83f5ee8..9f274bc8a 100644 --- a/src/Makefile.linux +++ b/src/Makefile.linux @@ -4,7 +4,7 @@ # change INCLUDES so it points to SDL2 headers directory: INCLUDES = -Iinclude -CC=gcc +CC = gcc LD = $(CC) CPPFLAGS = -DNDEBUG -D_THREAD_SAFE -D_REENTRANT @@ -12,7 +12,7 @@ CPPFLAGS+= -DSDL_DISABLE_IMMINTRIN_H CFLAGS = -fPIC -O3 -Wall LDFLAGS = -shared -Wl,-soname,libSDL-1.2.so.0 -#make sure this is supported: +# make sure this is supported: LDFLAGS+= -Wl,--no-undefined LDLIBS = -ldl @@ -21,15 +21,15 @@ SHLIB = libSDL-1.2.so.1.2.50 OBJ = SDL12_compat.o .SUFFIXES: -.SUFFIXES: .o .c .m +.SUFFIXES: .o .c all: $(SHLIB) $(SHLIB): $(OBJ) $(LD) -o $@ $(LDFLAGS) $(OBJ) $(LDLIBS) - ln -s $(SHLIB) libSDL-1.2.so - ln -s $(SHLIB) libSDL-1.2.so.0 - ln -s $(SHLIB) libSDL.so + ln -sf $(SHLIB) libSDL-1.2.so + ln -sf $(SHLIB) libSDL-1.2.so.0 + ln -sf $(SHLIB) libSDL.so .c.o: $(CC) $(CFLAGS) $(CPPFLAGS) $(INCLUDES) -o $@ -c $< diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 94b5b4273..1c951ca7f 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -5,11 +5,11 @@ INCLUDES = -Iinclude ifeq ($(CROSS),) -CC=gcc -RC=windres +CC = gcc +RC = windres else -CC=$(CROSS)-gcc -RC=$(CROSS)-windres +CC = $(CROSS)-gcc +RC = $(CROSS)-windres endif LD = $(CC) diff --git a/src/Makefile.vc b/src/Makefile.vc index d234e1577..151b4b250 100644 --- a/src/Makefile.vc +++ b/src/Makefile.vc @@ -31,6 +31,7 @@ all: $(DLLNAME) $(DLLNAME): $(OBJ) $(LD) /OUT:$@ $(LDFLAGS) $(OBJ) $(LDLIBS) + .c.obj: $(CC) $(CFLAGS) $(CPPFLAGS) $(INCLUDES) /Fo$@ -c $< .rc.res: From 16305a1e2c7dfc5361a2565b418a7f06edec8724 Mon Sep 17 00:00:00 2001 From: David Gow Date: Mon, 15 Nov 2021 12:04:58 +0800 Subject: [PATCH 156/606] README: Add some basic documentation for the config options we support --- README.md | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/README.md b/README.md index c2af48cca..f9dded719 100644 --- a/README.md +++ b/README.md @@ -34,3 +34,52 @@ compatibility and don't have a lot of documentation or fanciness at all. The new headers are also under the zlib license. Note that sdl12-compat itself does not use these headers, so if you just want the library, you don't need them. + +# Configuration options: + +sdl12-compat has a number of configuration options which can be used to work +around issues with individual applications, or to better fit your system or +preferences. + +These options are all specified as environment variables, and can be set by +running your application with them set on the command-line, for example: +``` +SDL12COMPAT_HIGHDPI=1 SDL12COMPAT_OPENGL_SCALING=0 %command% +``` +will run ``%command%`` with high-dpi monitor support enabled, but OpenGL +scaling support disabled. + +The available options are: + +- ``SDL12COMPAT_DEBUG_LOGGING`` — if enabled, print debugging messages to + ``stderr``. These messages are mostly useful to developers, or if trying to + track down a specific bug. +- ``SDL12COMPAT_FAKE_CDROM_PATH`` — a path to a directory containing MP3 files + (named trackXX.mp3, where XX is a two-digit track number) to be used by + applications which play CD audio. +- ``SDL12COMPAT_OPENGL_SCALING`` — enables scaling of OpenGL applications to + the current desktop resolution. If disabled, applications can change the + real screen resolution. This option is enabled by default, but not all + applications are compatible with it: try changing this if you can only see + a black screen. +- ``SDL12COMPAT_SYNC_TO_VBLANK`` — force the application to sync (or not sync) + to the vertical blanking interval (VSync). When enabled, this will cap the + application's framerate to the screen's refresh rate (and may resolve issues + with screen tearing). +- ``SDL12COMPAT_SCALE_METHOD`` — choose the scaling method used when + applications render at a non-native resolution. The options are ``nearest``, + for nearest-neighbour sampling (more pixelated) and ``linear`` for bilinear + sampling (blurrier). +- ``SDL12COMPAT_HIGHDPI`` — advertise the application as supporting high-DPI + displays. Enabling this will usually result in sharper graphics, but on some + applications text and other elements may become very small. +- ``SDL12COMPAT_USE_KEYBOARD_LAYOUT`` — make all keyboard input take the current + keyboard layout into account. This may need to be disabled for applications + which provide their own keyboard layout support, or if the position of the + keys on the keyboard is more important than the character they produce. Note + that text input (in most applications) will take the keyboard layout into + account regardless of this option. +- ``SDL_MOUSE_RELATIVE_SCALING`` — if enabled, relative mouse motion is scaled + when the application is running at a non-native resolution. This may be + required with some applications which use their own mouse cursors. See also + https://wiki.libsdl.org/SDL_HINT_MOUSE_RELATIVE_SCALING From 12f33fd0d0187d36b57a9fc3b4dc6ff460862553 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Tue, 16 Nov 2021 14:47:20 +0300 Subject: [PATCH 157/606] made README more readable locally on a computer rather than at Github. --- README.md | 77 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 45 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index f9dded719..43f17f50a 100644 --- a/README.md +++ b/README.md @@ -46,40 +46,53 @@ running your application with them set on the command-line, for example: ``` SDL12COMPAT_HIGHDPI=1 SDL12COMPAT_OPENGL_SCALING=0 %command% ``` -will run ``%command%`` with high-dpi monitor support enabled, but OpenGL +will run `%command%` with high-dpi monitor support enabled, but OpenGL scaling support disabled. The available options are: -- ``SDL12COMPAT_DEBUG_LOGGING`` — if enabled, print debugging messages to - ``stderr``. These messages are mostly useful to developers, or if trying to - track down a specific bug. -- ``SDL12COMPAT_FAKE_CDROM_PATH`` — a path to a directory containing MP3 files - (named trackXX.mp3, where XX is a two-digit track number) to be used by - applications which play CD audio. -- ``SDL12COMPAT_OPENGL_SCALING`` — enables scaling of OpenGL applications to - the current desktop resolution. If disabled, applications can change the - real screen resolution. This option is enabled by default, but not all - applications are compatible with it: try changing this if you can only see - a black screen. -- ``SDL12COMPAT_SYNC_TO_VBLANK`` — force the application to sync (or not sync) - to the vertical blanking interval (VSync). When enabled, this will cap the - application's framerate to the screen's refresh rate (and may resolve issues - with screen tearing). -- ``SDL12COMPAT_SCALE_METHOD`` — choose the scaling method used when - applications render at a non-native resolution. The options are ``nearest``, - for nearest-neighbour sampling (more pixelated) and ``linear`` for bilinear - sampling (blurrier). -- ``SDL12COMPAT_HIGHDPI`` — advertise the application as supporting high-DPI - displays. Enabling this will usually result in sharper graphics, but on some - applications text and other elements may become very small. -- ``SDL12COMPAT_USE_KEYBOARD_LAYOUT`` — make all keyboard input take the current - keyboard layout into account. This may need to be disabled for applications - which provide their own keyboard layout support, or if the position of the - keys on the keyboard is more important than the character they produce. Note - that text input (in most applications) will take the keyboard layout into - account regardless of this option. -- ``SDL_MOUSE_RELATIVE_SCALING`` — if enabled, relative mouse motion is scaled - when the application is running at a non-native resolution. This may be - required with some applications which use their own mouse cursors. See also +- SDL12COMPAT_DEBUG_LOGGING: + If enabled, print debugging messages to stderr. These messages are + mostly useful to developers, or when trying to track down a specific + bug. + +- SDL12COMPAT_FAKE_CDROM_PATH: + A path to a directory containing MP3 files (named trackXX.mp3, where + XX is a two-digit track number) to be used by applications which play + CD audio. + +- SDL12COMPAT_OPENGL_SCALING: + Enables scaling of OpenGL applications to the current desktop resolution. + If disabled, applications can change the real screen resolution. This + option is enabled by default, but not all applications are compatible + with it: try changing this if you can only see a black screen. + +- SDL12COMPAT_SYNC_TO_VBLANK: + Force the application to sync (or not sync) to the vertical blanking + interval (VSync). When enabled, this will cap the application's + framerate to the screen's refresh rate (and may resolve issues with + screen tearing). + +- SDL12COMPAT_SCALE_METHOD: + Choose the scaling method used when applications render at a non-native + resolution. The options are `nearest`, for nearest-neighbour sampling + (more pixelated) and `linear` for bilinear sampling (blurrier). + +- SDL12COMPAT_HIGHDPI: + Advertise the application as supporting high-DPI displays. Enabling + this will usually result in sharper graphics, but on some applications + text and other elements may become very small. + +- SDL12COMPAT_USE_KEYBOARD_LAYOUT: + Make all keyboard input take the current keyboard layout into account. + This may need to be disabled for applications which provide their own + keyboard layout support, or if the position of the keys on the keyboard + is more important than the character they produce. Note that text input + (in most applications) will take the keyboard layout into account + regardless of this option. + +- SDL_MOUSE_RELATIVE_SCALING: + If enabled, relative mouse motion is scaled when the application is + running at a non-native resolution. This may be required with some + applications which use their own mouse cursors. See also: https://wiki.libsdl.org/SDL_HINT_MOUSE_RELATIVE_SCALING From 7b9126180325496cc0f2179ca2d166eb5eaae3b6 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Wed, 17 Nov 2021 10:56:48 +0300 Subject: [PATCH 158/606] fixed windows build against latest SDL2 headers and added a FIXME note. --- src/SDL12_compat.c | 1 + src/SDL20_include_wrapper.h | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index a550b29d1..a1dc66422 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1259,6 +1259,7 @@ SDL_SetModuleHandle(void *handle) (void) handle;/* handled internally by SDL2 - nothing to do.. */ } +/* FIXME: forward these two to the SDL2 versions ? */ DECLSPEC int SDLCALL SDL_RegisterApp(char *name, Uint32 style, void *hInst) { diff --git a/src/SDL20_include_wrapper.h b/src/SDL20_include_wrapper.h index cfd1d8414..57d7ca5eb 100644 --- a/src/SDL20_include_wrapper.h +++ b/src/SDL20_include_wrapper.h @@ -98,6 +98,8 @@ #define SDL_VideoInit IGNORE_THIS_VERSION_OF_SDL_VideoInit #define SDL_BuildAudioCVT IGNORE_THIS_VERSION_OF_SDL_BuildAudioCVT #define SDL_ConvertAudio IGNORE_THIS_VERSION_OF_SDL_ConvertAudio +#define SDL_RegisterApp IGNORE_THIS_VERSION_OF_SDL_RegisterApp +#define SDL_UnregisterApp IGNORE_THIS_VERSION_OF_SDL_UnregisterApp #define BUILD_SDL 1 @@ -211,6 +213,8 @@ typedef void (__cdecl *pfnSDL_CurrentEndThread) (unsigned); #undef SDL_VideoInit #undef SDL_BuildAudioCVT #undef SDL_ConvertAudio +#undef SDL_RegisterApp +#undef SDL_UnregisterApp #ifdef SDL_mutexP #undef SDL_mutexP From 7df03158d31945d1491d4db51b85dd85f019c3e9 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Wed, 17 Nov 2021 11:35:02 +0300 Subject: [PATCH 159/606] tests: silenced several -Wwrite-strings warnings. --- test/loopwave.c | 7 +++---- test/testalpha.c | 2 +- test/testcdrom.c | 2 +- test/testiconv.c | 7 +++---- test/testoverlay.c | 4 ++-- test/testpalette.c | 2 +- test/testsprite.c | 2 +- test/testwin.c | 2 +- test/testwm.c | 7 +++++-- test/threadwin.c | 2 +- 10 files changed, 19 insertions(+), 18 deletions(-) diff --git a/test/loopwave.c b/test/loopwave.c index e1df747a7..426837377 100644 --- a/test/loopwave.c +++ b/test/loopwave.c @@ -63,17 +63,16 @@ void poked(int sig) int main(int argc, char *argv[]) { char name[32]; + const char *file; /* Load the SDL library */ if ( SDL_Init(SDL_INIT_AUDIO) < 0 ) { fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError()); return(1); } - if ( argv[1] == NULL ) { - argv[1] = "sample.wav"; - } + file = (argc < 2)? "sample.wav" : argv[1]; /* Load the wave file into memory */ - if ( SDL_LoadWAV(argv[1], + if ( SDL_LoadWAV(file, &wave.spec, &wave.sound, &wave.soundlen) == NULL ) { fprintf(stderr, "Couldn't load %s: %s\n", argv[1], SDL_GetError()); diff --git a/test/testalpha.c b/test/testalpha.c index 7e04fbe08..2ba899d03 100644 --- a/test/testalpha.c +++ b/test/testalpha.c @@ -178,7 +178,7 @@ static SDL_Rect position; static int x_vel, y_vel; static int alpha_vel; -int LoadSprite(SDL_Surface *screen, char *file) +int LoadSprite(SDL_Surface *screen, const char *file) { SDL_Surface *converted; diff --git a/test/testcdrom.c b/test/testcdrom.c index 2fc6daeb9..f1c4b2a34 100644 --- a/test/testcdrom.c +++ b/test/testcdrom.c @@ -51,7 +51,7 @@ static void ListTracks(SDL_CD *cdrom) { int i; int m, s, f; - char* trtype; + const char *trtype; SDL_CDStatus(cdrom); printf("Drive tracks: %d\n", cdrom->numtracks); diff --git a/test/testiconv.c b/test/testiconv.c index 5f1cff471..bc429a770 100644 --- a/test/testiconv.c +++ b/test/testiconv.c @@ -29,6 +29,7 @@ int main(int argc, char *argv[]) "UCS4", "UCS-4", }; + const char *fname; char buffer[BUFSIZ]; char *ucs4; char *test[2]; @@ -36,10 +37,8 @@ int main(int argc, char *argv[]) FILE *file; int errors = 0; - if ( !argv[1] ) { - argv[1] = "utf8.txt"; - } - file = fopen(argv[1], "rb"); + fname = (argc < 2) ? "utf8.txt" : argv[1]; + file = fopen(fname, "rb"); if ( !file ) { fprintf(stderr, "Unable to open %s\n", argv[1]); return (1); diff --git a/test/testoverlay.c b/test/testoverlay.c index b06d0fe0f..01ab8ed1c 100644 --- a/test/testoverlay.c +++ b/test/testoverlay.c @@ -324,7 +324,7 @@ int main(int argc, char **argv) int delay; int desired_bpp; Uint32 video_flags, overlay_format; - char *bmpfile; + const char *bmpfile; #ifdef BENCHMARK_SDL Uint32 then, now; #endif @@ -477,7 +477,7 @@ int main(int argc, char **argv) SDL_WM_SetCaption("SDL test overlay", "testoverlay"); /* Load picture */ - bmpfile=(argv[1]?argv[1]:"sample.bmp"); + bmpfile = argv[1] ? argv[1]:"sample.bmp"; pic = SDL_LoadBMP(bmpfile); if ( pic == NULL ) { fprintf(stderr, "Couldn't load %s: %s\n", bmpfile, diff --git a/test/testpalette.c b/test/testpalette.c index 2ad49164a..efa07327c 100644 --- a/test/testpalette.c +++ b/test/testpalette.c @@ -61,7 +61,7 @@ static void quit(int rc) exit(rc); } -static void sdlerr(char *when) +static void sdlerr(const char *when) { fprintf(stderr, "SDL error: %s: %s\n", when, SDL_GetError()); quit(1); diff --git a/test/testsprite.c b/test/testsprite.c index b777dbb8a..f83de9a14 100644 --- a/test/testsprite.c +++ b/test/testsprite.c @@ -28,7 +28,7 @@ static void quit(int rc) exit(rc); } -int LoadSprite(char *file) +int LoadSprite(const char *file) { SDL_Surface *temp; diff --git a/test/testwin.c b/test/testwin.c index 261ea9942..2fcbd1084 100644 --- a/test/testwin.c +++ b/test/testwin.c @@ -18,7 +18,7 @@ static void quit(int rc) exit(rc); } -void DrawPict(SDL_Surface *screen, char *bmpfile, +void DrawPict(SDL_Surface *screen, const char *bmpfile, int speedy, int flip, int nofade) { SDL_Surface *picture; diff --git a/test/testwm.c b/test/testwm.c index aef4e6002..04861562e 100644 --- a/test/testwm.c +++ b/test/testwm.c @@ -66,7 +66,7 @@ int SetVideoMode(int w, int h) return(0); } -SDL_Surface *LoadIconSurface(char *file, Uint8 **maskp) +SDL_Surface *LoadIconSurface(const char *file, Uint8 **maskp) { SDL_Surface *icon; Uint8 *pixels; @@ -348,6 +348,9 @@ int SDLCALL FilterEvents(const SDL_Event *event) } } + +static char testtitle[] = "Testing 1.. 2.. 3..."; + int main(int argc, char *argv[]) { SDL_Event event; @@ -414,7 +417,7 @@ int main(int argc, char *argv[]) /* Set the title bar */ if ( argv[1] == NULL ) - title = "Testing 1.. 2.. 3..."; + title = testtitle; else title = argv[1]; SDL_WM_SetCaption(title, "testwm"); diff --git a/test/threadwin.c b/test/threadwin.c index c704b30d1..761fdbc8f 100644 --- a/test/threadwin.c +++ b/test/threadwin.c @@ -21,7 +21,7 @@ static void quit(int rc) exit(rc); } -SDL_Surface *LoadIconSurface(char *file, Uint8 **maskp) +SDL_Surface *LoadIconSurface(const char *file, Uint8 **maskp) { SDL_Surface *icon; Uint8 *pixels; From 0aa0458577c4887e9a914dd30beb754859bff5ef Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Wed, 17 Nov 2021 17:56:00 +0300 Subject: [PATCH 160/606] SDL_endian.h: merged multiple updates from SDL2 --- include/SDL/SDL_endian.h | 91 ++++++++++++++++++++++++++-------------- 1 file changed, 60 insertions(+), 31 deletions(-) diff --git a/include/SDL/SDL_endian.h b/include/SDL/SDL_endian.h index 9072aaa2b..3e1496106 100644 --- a/include/SDL/SDL_endian.h +++ b/include/SDL/SDL_endian.h @@ -28,6 +28,10 @@ real SDL-1.2 available to you. */ #include "SDL_stdinc.h" +#if defined(_MSC_VER) && (_MSC_VER >= 1400) +#include +#endi + /* This is all lifted out of SDL2's zlib-licensed headers. */ #define SDL_LIL_ENDIAN 1234 @@ -40,7 +44,7 @@ real SDL-1.2 available to you. */ #elif defined(__OpenBSD__) #include #define SDL_BYTEORDER BYTE_ORDER -#elif defined(__FreeBSD__) +#elif defined(__FreeBSD__) || defined(__NetBSD__) #include #define SDL_BYTEORDER BYTE_ORDER #else @@ -58,25 +62,50 @@ real SDL-1.2 available to you. */ #include "begin_code.h" -#if (defined(__clang__) && (__clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 2))) || \ - (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))) +/* various modern compilers may have builtin swap */ +#if defined (__has_builtin) +#define _SDL_HAS_BUILTIN(x) __has_builtin(x) +#else +#define _SDL_HAS_BUILTIN(x) 0 +#endif + +#if defined(__GNUC__) +# define HAS_BUILTIN_BSWAP16 (_SDL_HAS_BUILTIN(__builtin_bswap16)) || \ + (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)) +# define HAS_BUILTIN_BSWAP32 (_SDL_HAS_BUILTIN(__builtin_bswap32)) || \ + (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) +# define HAS_BUILTIN_BSWAP64 (_SDL_HAS_BUILTIN(__builtin_bswap64)) || \ + (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) + + /* this one is broken */ +# define HAS_BROKEN_BSWAP (__GNUC__ == 2 && __GNUC_MINOR__ <= 95) +#else +# define HAS_BUILTIN_BSWAP16 0 +# define HAS_BUILTIN_BSWAP32 0 +# define HAS_BUILTIN_BSWAP64 0 +# define HAS_BROKEN_BSWAP 0 +#endif + +#if HAS_BUILTIN_BSWAP16 #define SDL_Swap16(x) __builtin_bswap16(x) -#elif defined(__GNUC__) && defined(__i386__) && \ - !(__GNUC__ == 2 && __GNUC_MINOR__ <= 95 /* broken gcc version */) +#elif defined(_MSC_VER) && (_MSC_VER >= 1400) +#pragma intrinsic(_byteswap_ushort) +#define SDL_Swap16(x) _byteswap_ushort(x) +#elif defined(__i386__) && !HAS_BROKEN_BSWAP static __inline__ Uint16 SDL_Swap16(Uint16 x) { __asm__("xchgb %b0,%h0": "=q"(x):"0"(x)); return x; } -#elif defined(__GNUC__) && defined(__x86_64__) +#elif defined(__x86_64__) static __inline__ Uint16 SDL_Swap16(Uint16 x) { __asm__("xchgb %b0,%h0": "=Q"(x):"0"(x)); return x; } -#elif defined(__GNUC__) && (defined(__powerpc__) || defined(__ppc__)) +#elif (defined(__powerpc__) || defined(__ppc__)) static __inline__ Uint16 SDL_Swap16(Uint16 x) { @@ -85,23 +114,20 @@ SDL_Swap16(Uint16 x) __asm__("rlwimi %0,%2,8,16,23": "=&r"(result):"0"(x >> 8), "r"(x)); return (Uint16)result; } -#elif defined(__GNUC__) && defined(__aarch64__) +#elif defined(__aarch64__) static __inline__ Uint16 SDL_Swap16(Uint16 x) { __asm__("rev16 %w1, %w0" : "=r"(x) : "r"(x)); return x; } -#elif defined(__GNUC__) && (defined(__m68k__) && !defined(__mcoldfire__)) +#elif (defined(__m68k__) && !defined(__mcoldfire__)) static __inline__ Uint16 SDL_Swap16(Uint16 x) { __asm__("rorw #8,%0": "=d"(x): "0"(x):"cc"); return x; } -#elif defined(_MSC_VER) -#pragma intrinsic(_byteswap_ushort) -#define SDL_Swap16(x) _byteswap_ushort(x) #elif defined(__WATCOMC__) && defined(__386__) extern _inline Uint16 SDL_Swap16(Uint16); #pragma aux SDL_Swap16 = \ @@ -116,25 +142,26 @@ SDL_Swap16(Uint16 x) } #endif -#if (defined(__clang__) && (__clang_major__ > 2 || (__clang_major__ == 2 && __clang_minor__ >= 6))) || \ - (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) +#if HAS_BUILTIN_BSWAP32 #define SDL_Swap32(x) __builtin_bswap32(x) -#elif defined(__GNUC__) && defined(__i386__) && \ - !(__GNUC__ == 2 && __GNUC_MINOR__ <= 95 /* broken gcc version */) +#elif defined(_MSC_VER) && (_MSC_VER >= 1400) +#pragma intrinsic(_byteswap_ulong) +#define SDL_Swap32(x) _byteswap_ulong(x) +#elif defined(__i386__) && !HAS_BROKEN_BSWAP static __inline__ Uint32 SDL_Swap32(Uint32 x) { __asm__("bswap %0": "=r"(x):"0"(x)); return x; } -#elif defined(__GNUC__) && defined(__x86_64__) +#elif defined(__x86_64__) static __inline__ Uint32 SDL_Swap32(Uint32 x) { __asm__("bswapl %0": "=r"(x):"0"(x)); return x; } -#elif defined(__GNUC__) && (defined(__powerpc__) || defined(__ppc__)) +#elif (defined(__powerpc__) || defined(__ppc__)) static __inline__ Uint32 SDL_Swap32(Uint32 x) { @@ -145,14 +172,14 @@ SDL_Swap32(Uint32 x) __asm__("rlwimi %0,%2,24,0,7" : "=&r"(result): "0" (result), "r"(x)); return result; } -#elif defined(__GNUC__) && defined(__aarch64__) +#elif defined(__aarch64__) static __inline__ Uint32 SDL_Swap32(Uint32 x) { __asm__("rev %w1, %w0": "=r"(x):"r"(x)); return x; } -#elif defined(__GNUC__) && (defined(__m68k__) && !defined(__mcoldfire__)) +#elif (defined(__m68k__) && !defined(__mcoldfire__)) static __inline__ Uint32 SDL_Swap32(Uint32 x) { @@ -165,9 +192,6 @@ extern _inline Uint32 SDL_Swap32(Uint32); "bswap eax" \ parm [eax] \ modify [eax]; -#elif defined(_MSC_VER) -#pragma intrinsic(_byteswap_ulong) -#define SDL_Swap32(x) _byteswap_ulong(x) #else static __inline__ Uint32 SDL_Swap32(Uint32 x) @@ -177,11 +201,12 @@ SDL_Swap32(Uint32 x) } #endif -#if (defined(__clang__) && (__clang_major__ > 2 || (__clang_major__ == 2 && __clang_minor__ >= 6))) || \ - (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) +#if HAS_BUILTIN_BSWAP64 #define SDL_Swap64(x) __builtin_bswap64(x) -#elif defined(__GNUC__) && defined(__i386__) && \ - !(__GNUC__ == 2 && __GNUC_MINOR__ <= 95 /* broken gcc version */) +#elif defined(_MSC_VER) && (_MSC_VER >= 1400) +#pragma intrinsic(_byteswap_uint64) +#define SDL_Swap64(x) _byteswap_uint64(x) +#elif defined(__i386__) && !HAS_BROKEN_BSWAP static __inline__ Uint64 SDL_Swap64(Uint64 x) { @@ -197,7 +222,7 @@ SDL_Swap64(Uint64 x) : "0" (v.s.a), "1"(v.s.b)); return v.u; } -#elif defined(__GNUC__) && defined(__x86_64__) +#elif defined(__x86_64__) static __inline__ Uint64 SDL_Swap64(Uint64 x) { @@ -212,9 +237,6 @@ extern _inline Uint64 SDL_Swap64(Uint64); "xchg eax,edx" \ parm [eax edx] \ modify [eax edx]; -#elif defined(_MSC_VER) -#pragma intrinsic(_byteswap_uint64) -#define SDL_Swap64(x) _byteswap_uint64(x) #else static __inline__ Uint64 SDL_Swap64(Uint64 x) @@ -232,6 +254,13 @@ SDL_Swap64(Uint64 x) } #endif +/* remove extra macros */ +#undef HAS_BROKEN_BSWAP +#undef HAS_BUILTIN_BSWAP16 +#undef HAS_BUILTIN_BSWAP32 +#undef HAS_BUILTIN_BSWAP64 +#undef _SDL_HAS_BUILTIN + /** * \name Swap to native * Byteswap item from the specified endianness to the native endianness. From 3bca81f4ce9e001bb0becac3e7eb6869e499e796 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Wed, 17 Nov 2021 17:56:50 +0300 Subject: [PATCH 161/606] fixed typo in previous commit --- include/SDL/SDL_endian.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/include/SDL/SDL_endian.h b/include/SDL/SDL_endian.h index 3e1496106..7fc0f1f48 100644 --- a/include/SDL/SDL_endian.h +++ b/include/SDL/SDL_endian.h @@ -30,7 +30,7 @@ real SDL-1.2 available to you. */ #if defined(_MSC_VER) && (_MSC_VER >= 1400) #include -#endi +#endif /* This is all lifted out of SDL2's zlib-licensed headers. */ @@ -290,4 +290,3 @@ SDL_Swap64(Uint64 x) #include "close_code.h" #endif - From cb25cfcaa4a2a75260cbbb303d2f30a64c19ba64 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Wed, 17 Nov 2021 20:00:02 +0300 Subject: [PATCH 162/606] README.md: minor re-ordering of options documentation --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 43f17f50a..ef06c27dc 100644 --- a/README.md +++ b/README.md @@ -67,12 +67,6 @@ The available options are: option is enabled by default, but not all applications are compatible with it: try changing this if you can only see a black screen. -- SDL12COMPAT_SYNC_TO_VBLANK: - Force the application to sync (or not sync) to the vertical blanking - interval (VSync). When enabled, this will cap the application's - framerate to the screen's refresh rate (and may resolve issues with - screen tearing). - - SDL12COMPAT_SCALE_METHOD: Choose the scaling method used when applications render at a non-native resolution. The options are `nearest`, for nearest-neighbour sampling @@ -83,6 +77,12 @@ The available options are: this will usually result in sharper graphics, but on some applications text and other elements may become very small. +- SDL12COMPAT_SYNC_TO_VBLANK: + Force the application to sync (or not sync) to the vertical blanking + interval (VSync). When enabled, this will cap the application's + framerate to the screen's refresh rate (and may resolve issues with + screen tearing). + - SDL12COMPAT_USE_KEYBOARD_LAYOUT: Make all keyboard input take the current keyboard layout into account. This may need to be disabled for applications which provide their own From 5ee2ad51dc407d8eede8fb492692c0a555c64bf9 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Thu, 18 Nov 2021 03:33:00 +0300 Subject: [PATCH 163/606] SDL_endian.h: sync with SDL2 --- include/SDL/SDL_endian.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/SDL/SDL_endian.h b/include/SDL/SDL_endian.h index 7fc0f1f48..09ccb14c1 100644 --- a/include/SDL/SDL_endian.h +++ b/include/SDL/SDL_endian.h @@ -69,7 +69,7 @@ real SDL-1.2 available to you. */ #define _SDL_HAS_BUILTIN(x) 0 #endif -#if defined(__GNUC__) +#if defined(__GNUC__) || defined(__clang__) # define HAS_BUILTIN_BSWAP16 (_SDL_HAS_BUILTIN(__builtin_bswap16)) || \ (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)) # define HAS_BUILTIN_BSWAP32 (_SDL_HAS_BUILTIN(__builtin_bswap32)) || \ From e19f842e54817874e3d298327dcc9cd7fc380f20 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Thu, 18 Nov 2021 14:33:32 +0300 Subject: [PATCH 164/606] SDL-1.2 has no SDL_SwapFloat --- include/SDL/SDL_endian.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/include/SDL/SDL_endian.h b/include/SDL/SDL_endian.h index 09ccb14c1..2e50eb9be 100644 --- a/include/SDL/SDL_endian.h +++ b/include/SDL/SDL_endian.h @@ -270,20 +270,16 @@ SDL_Swap64(Uint64 x) #define SDL_SwapLE16(X) (X) #define SDL_SwapLE32(X) (X) #define SDL_SwapLE64(X) (X) -#define SDL_SwapFloatLE(X) (X) #define SDL_SwapBE16(X) SDL_Swap16(X) #define SDL_SwapBE32(X) SDL_Swap32(X) #define SDL_SwapBE64(X) SDL_Swap64(X) -#define SDL_SwapFloatBE(X) SDL_SwapFloat(X) #else #define SDL_SwapLE16(X) SDL_Swap16(X) #define SDL_SwapLE32(X) SDL_Swap32(X) #define SDL_SwapLE64(X) SDL_Swap64(X) -#define SDL_SwapFloatLE(X) SDL_SwapFloat(X) #define SDL_SwapBE16(X) (X) #define SDL_SwapBE32(X) (X) #define SDL_SwapBE64(X) (X) -#define SDL_SwapFloatBE(X) (X) #endif /* @} *//* Swap to native */ From d926510df0c8b24ccf8aa43056108ec84e21367a Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sat, 20 Nov 2021 01:01:10 +0300 Subject: [PATCH 165/606] tests: fixed two oversights in the previous -Wwrite-strings patch. --- test/loopwave.c | 8 +++----- test/testiconv.c | 5 +++-- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/test/loopwave.c b/test/loopwave.c index 426837377..414b9eda0 100644 --- a/test/loopwave.c +++ b/test/loopwave.c @@ -70,12 +70,10 @@ int main(int argc, char *argv[]) fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError()); return(1); } - file = (argc < 2)? "sample.wav" : argv[1]; + file = (argc < 2) ? "sample.wav" : argv[1]; /* Load the wave file into memory */ - if ( SDL_LoadWAV(file, - &wave.spec, &wave.sound, &wave.soundlen) == NULL ) { - fprintf(stderr, "Couldn't load %s: %s\n", - argv[1], SDL_GetError()); + if ( SDL_LoadWAV(file, &wave.spec, &wave.sound, &wave.soundlen) == NULL ) { + fprintf(stderr, "Couldn't load %s: %s\n", file, SDL_GetError()); quit(1); } diff --git a/test/testiconv.c b/test/testiconv.c index bc429a770..7e71320c1 100644 --- a/test/testiconv.c +++ b/test/testiconv.c @@ -29,7 +29,8 @@ int main(int argc, char *argv[]) "UCS4", "UCS-4", }; - const char *fname; + + const char * fname; char buffer[BUFSIZ]; char *ucs4; char *test[2]; @@ -40,7 +41,7 @@ int main(int argc, char *argv[]) fname = (argc < 2) ? "utf8.txt" : argv[1]; file = fopen(fname, "rb"); if ( !file ) { - fprintf(stderr, "Unable to open %s\n", argv[1]); + fprintf(stderr, "Unable to open %s\n", fname); return (1); } From 5bc0e0a2fd5de6b919fc1a4ce37996312d29fbf0 Mon Sep 17 00:00:00 2001 From: David Gow Date: Sun, 21 Nov 2021 14:54:04 +0800 Subject: [PATCH 166/606] glRenderbufferStorage() is a part of core GL 3. --- src/SDL12_compat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index a1dc66422..7e622ff0c 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -4886,7 +4886,7 @@ InitializeOpenGLScaling(const int w, const int h) OpenGLFuncs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, OpenGLLogicalScalingMultisampleColor); OpenGLFuncs.glGenRenderbuffers(1, &OpenGLLogicalScalingMultisampleDepth); OpenGLFuncs.glBindRenderbuffer(GL_RENDERBUFFER, OpenGLLogicalScalingMultisampleDepth); - OpenGLFuncs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, w, h); FIXME("is an extension (or core 3.0)?"); + OpenGLFuncs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, w, h); OpenGLFuncs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, OpenGLLogicalScalingMultisampleDepth); OpenGLFuncs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, OpenGLLogicalScalingMultisampleDepth); OpenGLFuncs.glBindRenderbuffer(GL_RENDERBUFFER, 0); From d41f3cc6fe6b7e605316ffe7afb6a3abe71f5ec5 Mon Sep 17 00:00:00 2001 From: David Gow Date: Mon, 22 Nov 2021 11:42:33 +0800 Subject: [PATCH 167/606] Improve support for SDL_VIDEO_FULLSCREEN_DISPLAY, remove FIXME SDL_VIDEO_FULLSCREEN_DISPLAY worked in some cases (where the window was being centered, and for some -- but not all -- lookups of available video modes), but had several flaws. Fix it by: - Using VideoDisplayIndex in all places where the current display is read. - Setting x and y to SDL_WINDOWPOS_UNDEFINED_DISPLAY(display) as a fallback in GetEnvironmentWindowPosition() - Handling the case where SDL_VIDEO_FULLSCREEN_DISPLAY is out-of-bounds by falling back to zero. --- src/SDL12_compat.c | 12 ++++++++++-- src/SDL20_syms.h | 1 + 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 7e622ff0c..06032f5c1 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1569,6 +1569,12 @@ GetVideoDisplay(void) variable = SDL20_getenv("SDL_VIDEO_FULLSCREEN_HEAD"); } if (variable) { + int preferred_display = SDL20_atoi(variable); + + if (preferred_display < 0 || preferred_display >= SDL20_GetNumVideoDisplays()) { + return 0; + } + return SDL20_atoi(variable); } else { return 0; @@ -4579,6 +4585,9 @@ GetEnvironmentWindowPosition(int *x, int *y) if (center) { *x = SDL_WINDOWPOS_CENTERED_DISPLAY(display); *y = SDL_WINDOWPOS_CENTERED_DISPLAY(display); + } else { + *x = SDL_WINDOWPOS_UNDEFINED_DISPLAY(display); + *y = SDL_WINDOWPOS_UNDEFINED_DISPLAY(display); } } @@ -4969,8 +4978,7 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12) return NULL; } - FIXME("There's an environment variable to choose a display"); - if (SDL20_GetCurrentDisplayMode(0, &dmode) < 0) { + if (SDL20_GetCurrentDisplayMode(VideoDisplayIndex, &dmode) < 0) { return NULL; } diff --git a/src/SDL20_syms.h b/src/SDL20_syms.h index 417e325f5..c30114ff7 100644 --- a/src/SDL20_syms.h +++ b/src/SDL20_syms.h @@ -74,6 +74,7 @@ SDL20_SYM(Uint8,EventState,(Uint32 a, int b),(a,b),return) SDL20_SYM(SDL_bool,GetWindowWMInfo,(SDL_Window *a, SDL_SysWMinfo *b),(a,b),) +SDL20_SYM(int,GetNumVideoDisplays,(void),(),return) SDL20_SYM(int,GetNumDisplayModes,(int a),(a),return) SDL20_SYM(int,GetDisplayMode,(int a, int b, SDL_DisplayMode *c),(a,b,c),return) SDL20_SYM(int,GetDesktopDisplayMode,(int a, SDL_DisplayMode *b),(a,b),return) From 9e43523acab0d282fffb3a0dbe53aa7eb3b4273a Mon Sep 17 00:00:00 2001 From: David Gow Date: Mon, 22 Nov 2021 12:28:09 +0800 Subject: [PATCH 168/606] Time presentation of partial screen updates based on refresh rate Currently, for applications which update only part of the screen, we present the screen every 15ms. Instead, update based on the refresh rate. For fullscreen applications, this will be the refresh rate of the screen they're on, for windowed applications, we use the refresh rate of the display selected with SDL_VIDEO_FULLSCREEN_DISPLAY. The calculation is split out into the GetDesiredMillisecondsPerFrame() function, which is then used for both YUV and UpdateRects() updates. --- src/SDL12_compat.c | 26 ++++++++++++++++++++++---- src/SDL20_syms.h | 1 + 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 06032f5c1..aa42a2c4a 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -5581,6 +5581,26 @@ UpdateRect12to20(SDL12_Surface *surface12, const SDL12_Rect *rect12, SDL_Rect *r } } +/* For manual throttling of screen updates. */ +static int +GetDesiredMillisecondsPerFrame() +{ + SDL_DisplayMode mode; + if (VideoSurface12->flags & SDL12_FULLSCREEN) { + if (SDL20_GetWindowDisplayMode(VideoWindow20, &mode) == 0) { + if (mode.refresh_rate) { + return 1000 / mode.refresh_rate; + } + } + } else if (SDL20_GetCurrentDisplayMode(VideoDisplayIndex, &mode) == 0) { + /* If we're windowed, assume we're on the default screen. */ + if (mode.refresh_rate) { + return 1000 / mode.refresh_rate; + } + } + return 15; +} + /* SDL_OPENGLBLIT support APIs. https://discourse.libsdl.org/t/ogl-and-sdl/2775/3 */ DECLSPEC void SDLCALL SDL_GL_Lock(void) @@ -5767,9 +5787,7 @@ SDL_UpdateRects(SDL12_Surface *surface12, int numrects, SDL12_Rect *rects12) if (whole_screen) { PresentScreen(); /* flip it now. */ } else { - FIXME("Don't hardcode 15, do this based on display refresh rate."); - FIXME("Maybe just flip it immediately in PumpEvents if this flag is set, instead?"); - VideoSurfacePresentTicks = VideoSurfaceLastPresentTicks + 15; /* flip it later. */ + VideoSurfacePresentTicks = VideoSurfaceLastPresentTicks + GetDesiredMillisecondsPerFrame(); /* flip it later. */ } } } @@ -6327,7 +6345,7 @@ SDL_DisplayYUVOverlay(SDL12_Overlay *overlay12, SDL12_Rect *dstrect12) FIXME("is it legal to display multiple yuv overlays?"); /* if so, this will need to be a list instead of a single pointer. */ QueuedDisplayOverlay12 = overlay12; SDL20_memcpy(&QueuedDisplayOverlayDstRect12, dstrect12, sizeof (SDL12_Rect)); - VideoSurfacePresentTicks = VideoSurfaceLastPresentTicks + 15; /* flip it later. */ + VideoSurfacePresentTicks = VideoSurfaceLastPresentTicks + GetDesiredMillisecondsPerFrame(); /* flip it later. */ return 0; } diff --git a/src/SDL20_syms.h b/src/SDL20_syms.h index c30114ff7..77cc48e69 100644 --- a/src/SDL20_syms.h +++ b/src/SDL20_syms.h @@ -79,6 +79,7 @@ SDL20_SYM(int,GetNumDisplayModes,(int a),(a),return) SDL20_SYM(int,GetDisplayMode,(int a, int b, SDL_DisplayMode *c),(a,b,c),return) SDL20_SYM(int,GetDesktopDisplayMode,(int a, SDL_DisplayMode *b),(a,b),return) SDL20_SYM(int,GetCurrentDisplayMode,(int a, SDL_DisplayMode *b),(a,b),return) +SDL20_SYM(int,GetWindowDisplayMode,(SDL_Window *a, SDL_DisplayMode *b),(a,b),return) SDL20_SYM(void,EnableScreenSaver,(void),(),) SDL20_SYM(void,DisableScreenSaver,(void),(),) From 713a2ecc5f2499be1cbd0842285e0b9cbb3f5047 Mon Sep 17 00:00:00 2001 From: David Gow Date: Mon, 22 Nov 2021 14:31:16 +0800 Subject: [PATCH 169/606] Make SDL_EnableKeyRepeat() just use the SDL2 repeat field This isn't a proper implementation which supports the corrent delay and interval fields, but I still think it's better than nothing. In particular, while we were trying to suppress key repeat events before, we still got them because of SDL_TEXTINPUT events, which took repeat into account, so if repeat is disabled, we just get a bunch of events with SDLK_UNKNOWN (and a valid unicode char). Now, if key repeat is enabled, at least those events look sensible, even if the timing is not exactly what might've been wanted. --- src/SDL12_compat.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index aa42a2c4a..351b9a340 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -923,6 +923,7 @@ static char *WindowTitle = NULL; static char *WindowIconTitle = NULL; static SDL_Surface *VideoIcon20 = NULL; static int EnabledUnicode = 0; +static SDL_bool EnabledKeyRepeat = SDL_TRUE; /* Windows SDL1.2 never uses translated keyboard layouts for compatibility with DirectInput, which didn't support them. Other platforms (MacOS, Linux) seem to, but with varying levels of bugginess. So default to Translated Layouts on @@ -3785,7 +3786,7 @@ EventFilter20to12(void *data, SDL_Event *event20) case SDL_KEYDOWN: FlushPendingKeydownEvent(0); - if (event20->key.repeat) { + if (event20->key.repeat && !EnabledKeyRepeat) { return 1; /* ignore 2.0-style key repeat events */ } @@ -6569,21 +6570,22 @@ SDL_GetGammaRamp(Uint16 *red, Uint16 *green, Uint16 *blue) DECLSPEC int SDLCALL SDL_EnableKeyRepeat(int delay, int interval) { - FIXME("write me"); - (void) delay; + FIXME("Support non-default delay and interval for Key Repeat"); (void) interval; + + EnabledKeyRepeat = (delay != 0) ? SDL_TRUE : SDL_FALSE; + return 0; } DECLSPEC void SDLCALL SDL_GetKeyRepeat(int *delay, int *interval) { - FIXME("write me"); if (delay) { - *delay = SDL12_DEFAULT_REPEAT_DELAY; + *delay = EnabledKeyRepeat ? SDL12_DEFAULT_REPEAT_DELAY : 0; } if (interval) { - *interval = SDL12_DEFAULT_REPEAT_INTERVAL; + *interval = EnabledKeyRepeat ? SDL12_DEFAULT_REPEAT_INTERVAL : 0; } } From 5b594938711fbed30c6fcec7e4378653db92d723 Mon Sep 17 00:00:00 2001 From: David Gow Date: Mon, 22 Nov 2021 17:42:08 +0800 Subject: [PATCH 170/606] Add some notes about compatibility issues to the README (issue #144) Add two sections to the README about different compatibility issues: 1. Issues with OpenGL Scaling 2. Other issues with apps which access APIs directly. In both cases, this is usually the fault of an OpenGL extension loader, sometimes deep in a library. --- README.md | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/README.md b/README.md index ef06c27dc..942bc9497 100644 --- a/README.md +++ b/README.md @@ -96,3 +96,41 @@ The available options are: running at a non-native resolution. This may be required with some applications which use their own mouse cursors. See also: https://wiki.libsdl.org/SDL_HINT_MOUSE_RELATIVE_SCALING + +# Compatibility issues with OpenGL scaling + +The OpenGL scaling feature of sdl12-compat allows applications which wish to +run at a non-native screen resolution to do so without changing the system +resolution. It does this by redirecting OpenGL rendering calls to a "fake" +backbuffer which is scaled when rendering. + +This works well for simple applications, but for more complicated applications +which use Frame Buffer Objects, sdl12-compat needs to intercept and redirect +some OpenGL calls. Applications which access these functions without going +though SDL (even if via a library) may not successfully render anything, or +may render incorrectly if OpenGL scaling is enabled. + +In these cases, you can disable OpenGL scaling by setting the environment +variable: +``` +SDL12COMPAT_OPENGL_SCALING=0 +``` + +# Compatibility issues with applications directly accessing underlying APIs + +Some applications combine the use of SDL with direct access to the underlying +OS or window system. When running these applications on the same OS and SDL +video driver (e.g. a program written for X11 on Linux is run on X11 on Linux), +sdl12-compat is usually compatible. + +However, if you wish to run an application on a different video driver, the +application will be unable to access the underlying API it is expecting, and +may fail. This often occurs trying to run applications written for X11 under +Wayland, and particularly affects a number of popular OpenGL extension loaders. + +In this case, the best workaround is to run under a compatibility layer like +XWayland, and set the SDL_VIDEODRIVER environment variable to the driver the +program is expecting: +``` +SDL_VIDEODRIVER=x11 +``` From a25582727501c115df554b889801107851282839 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Wed, 24 Nov 2021 17:02:02 +0300 Subject: [PATCH 171/606] SDL_endian.h: minor cleanup for watcom _inline keyword. --- include/SDL/SDL_endian.h | 14 ++++++++------ src/SDL12_compat.c | 2 +- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/include/SDL/SDL_endian.h b/include/SDL/SDL_endian.h index 2e50eb9be..4718b9850 100644 --- a/include/SDL/SDL_endian.h +++ b/include/SDL/SDL_endian.h @@ -34,8 +34,8 @@ real SDL-1.2 available to you. */ /* This is all lifted out of SDL2's zlib-licensed headers. */ -#define SDL_LIL_ENDIAN 1234 -#define SDL_BIG_ENDIAN 4321 +#define SDL_LIL_ENDIAN 1234 +#define SDL_BIG_ENDIAN 4321 #ifndef SDL_BYTEORDER /* Not defined in SDL_config.h? */ #ifdef __linux__ @@ -60,6 +60,7 @@ real SDL-1.2 available to you. */ #endif /* __linux__ */ #endif /* !SDL_BYTEORDER */ + #include "begin_code.h" /* various modern compilers may have builtin swap */ @@ -129,7 +130,7 @@ SDL_Swap16(Uint16 x) return x; } #elif defined(__WATCOMC__) && defined(__386__) -extern _inline Uint16 SDL_Swap16(Uint16); +extern __inline Uint16 SDL_Swap16(Uint16); #pragma aux SDL_Swap16 = \ "xchg al, ah" \ parm [ax] \ @@ -187,7 +188,7 @@ SDL_Swap32(Uint32 x) return x; } #elif defined(__WATCOMC__) && defined(__386__) -extern _inline Uint32 SDL_Swap32(Uint32); +extern __inline Uint32 SDL_Swap32(Uint32); #pragma aux SDL_Swap32 = \ "bswap eax" \ parm [eax] \ @@ -230,7 +231,7 @@ SDL_Swap64(Uint64 x) return x; } #elif defined(__WATCOMC__) && defined(__386__) -extern _inline Uint64 SDL_Swap64(Uint64); +extern __inline Uint64 SDL_Swap64(Uint64); #pragma aux SDL_Swap64 = \ "bswap eax" \ "bswap edx" \ @@ -254,6 +255,7 @@ SDL_Swap64(Uint64 x) } #endif + /* remove extra macros */ #undef HAS_BROKEN_BSWAP #undef HAS_BUILTIN_BSWAP16 @@ -285,4 +287,4 @@ SDL_Swap64(Uint64 x) #include "close_code.h" -#endif +#endif /* _SDL_endian_h */ diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 351b9a340..6dc9b7ec0 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -110,7 +110,7 @@ extern "C" { /* From SDL2.0's SDL_bits.h: a force-inlined function. */ #if defined(__WATCOMC__) && defined(__386__) -extern _inline int _SDL20_bsr_watcom (Uint32); +extern __inline int _SDL20_bsr_watcom(Uint32); #pragma aux _SDL20_bsr_watcom = \ "bsr eax, eax" \ parm [eax] nomemory \ From 6e23e25752dea62c75be54f00ace08f0daef263f Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Thu, 25 Nov 2021 14:50:04 +0300 Subject: [PATCH 172/606] SDL_endian.h: remove aarch64 asm. --- include/SDL/SDL_endian.h | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/include/SDL/SDL_endian.h b/include/SDL/SDL_endian.h index 4718b9850..872f31082 100644 --- a/include/SDL/SDL_endian.h +++ b/include/SDL/SDL_endian.h @@ -115,13 +115,6 @@ SDL_Swap16(Uint16 x) __asm__("rlwimi %0,%2,8,16,23": "=&r"(result):"0"(x >> 8), "r"(x)); return (Uint16)result; } -#elif defined(__aarch64__) -static __inline__ Uint16 -SDL_Swap16(Uint16 x) -{ - __asm__("rev16 %w1, %w0" : "=r"(x) : "r"(x)); - return x; -} #elif (defined(__m68k__) && !defined(__mcoldfire__)) static __inline__ Uint16 SDL_Swap16(Uint16 x) @@ -173,13 +166,6 @@ SDL_Swap32(Uint32 x) __asm__("rlwimi %0,%2,24,0,7" : "=&r"(result): "0" (result), "r"(x)); return result; } -#elif defined(__aarch64__) -static __inline__ Uint32 -SDL_Swap32(Uint32 x) -{ - __asm__("rev %w1, %w0": "=r"(x):"r"(x)); - return x; -} #elif (defined(__m68k__) && !defined(__mcoldfire__)) static __inline__ Uint32 SDL_Swap32(Uint32 x) From 4e4527a123fb99a1677055d89c5fc74323ddc4d8 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Thu, 25 Nov 2021 23:11:50 +0300 Subject: [PATCH 173/606] SDL_win32_main.c: put back isspace() macro again : because HAVE_CTYPE_H is not defined for windows here. used a short version of SDL_isspace instead (like the original macro for wince.) --- src/SDLmain/win32/SDL_win32_main.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/SDLmain/win32/SDL_win32_main.c b/src/SDLmain/win32/SDL_win32_main.c index fd7fdfd86..99ded4e4a 100644 --- a/src/SDLmain/win32/SDL_win32_main.c +++ b/src/SDLmain/win32/SDL_win32_main.c @@ -26,6 +26,9 @@ #define STDOUT_FILE "stdout.txt" #define STDERR_FILE "stderr.txt" +#undef SDL_isspace +#define SDL_isspace(a) ((a) == ' ' || (a) == '\t') + /* Set a variable to tell if the stdio redirect has been enabled. */ static int stdioRedirectEnabled = 0; @@ -63,7 +66,7 @@ static int ParseCommandLine(char *cmdline, char **argv) argc = last_argc = 0; for ( bufp = cmdline; *bufp; ) { /* Skip leading whitespace */ - while ( isspace(*bufp) ) { + while ( SDL_isspace(*bufp) ) { ++bufp; } /* Skip over argument */ @@ -88,7 +91,7 @@ static int ParseCommandLine(char *cmdline, char **argv) ++argc; } /* Skip over word */ - while ( *bufp && ! isspace(*bufp) ) { + while ( *bufp && ! SDL_isspace(*bufp) ) { ++bufp; } } From c7d6a9c8e1f0c8e8dfdbff764198c8060805d722 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 2 Dec 2021 10:23:48 -0500 Subject: [PATCH 174/606] SDL_SetVideoMode: do window resize twice to workaround SDL2 (x11?) issue. It looks like at the moment SDL2/x11 misbehaves if you resize a fullscreen window with SDL_SetWindowSize and then make it not fullscreen with SDL_SetWindowFullscreen; it doesn't appear to accept the new window size when it leaves fullscreen mode. But a second SDL_SetWindowSize() at this point appears to be accepted. I believe this to be an SDL2 issue, but the workaround is easy enough, that we'll keep this for older SDLs even if a newer release fixes the issue. Fixes #148. --- src/SDL12_compat.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 6dc9b7ec0..289bbbb2e 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -5073,6 +5073,8 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12) } else { /* resize it */ SDL20_SetWindowSize(VideoWindow20, width, height); SDL20_SetWindowFullscreen(VideoWindow20, fullscreen_flags20); + /* This second SetWindowSize is a workaround for an SDL2 bug, see https://github.com/libsdl-org/sdl12-compat/issues/148 */ + SDL20_SetWindowSize(VideoWindow20, width, height); SDL20_SetWindowBordered(VideoWindow20, (flags12 & SDL12_NOFRAME) ? SDL_FALSE : SDL_TRUE); SDL20_SetWindowResizable(VideoWindow20, (flags12 & SDL12_RESIZABLE) ? SDL_TRUE : SDL_FALSE); } From f83cde974bf9cf3ef9cc4583acdab645678899b5 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Thu, 2 Dec 2021 18:39:40 +0300 Subject: [PATCH 175/606] adjust the os/2 dll name in cmake the script. --- CMakeLists.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 61b5a3969..2233a8b44 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -90,6 +90,12 @@ elseif(UNIX AND NOT ANDROID) VERSION "${SDL12_COMPAT_VERSION_STR}" SOVERSION "0" OUTPUT_NAME "SDL-1.2") +elseif(OS2) + # OS/2 version was built as SDL12.dll + set_target_properties(SDL PROPERTIES + VERSION "${SDL12_COMPAT_VERSION_STR}" + SOVERSION "0" + OUTPUT_NAME "SDL12") else() set_target_properties(SDL PROPERTIES VERSION "${SDL12_COMPAT_VERSION_STR}" From 4601def7935f8800b0b32750db84aa66823579b8 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 3 Dec 2021 10:21:34 -0500 Subject: [PATCH 176/606] OpenGL Logical Scaling: Add an alpha channel if the app requests it. Fixes #149. --- src/SDL12_compat.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 289bbbb2e..e389c9e31 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -4853,6 +4853,7 @@ static SDL_bool InitializeOpenGLScaling(const int w, const int h) { const char *env; + int alpha_size = 0; /* Support the MOUSE_RELATIVE_SCALING hint from SDL 2.0 for OpenGL scaling. */ env = SDL20_getenv("SDL_MOUSE_RELATIVE_SCALING"); @@ -4865,11 +4866,14 @@ InitializeOpenGLScaling(const int w, const int h) OpenGLFuncs.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); SDL20_GL_SwapWindow(VideoWindow20); + FIXME("This should check if app requested a depth buffer, etc, too."); + SDL20_GL_GetAttribute(SDL_GL_ALPHA_SIZE, &alpha_size); + OpenGLFuncs.glGenFramebuffers(1, &OpenGLLogicalScalingFBO); OpenGLFuncs.glBindFramebuffer(GL_FRAMEBUFFER, OpenGLLogicalScalingFBO); OpenGLFuncs.glGenRenderbuffers(1, &OpenGLLogicalScalingColor); OpenGLFuncs.glBindRenderbuffer(GL_RENDERBUFFER, OpenGLLogicalScalingColor); - OpenGLFuncs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, OpenGLLogicalScalingSamples, GL_RGB8, w, h); + OpenGLFuncs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, OpenGLLogicalScalingSamples, (alpha_size > 0) ? GL_RGBA8 : GL_RGB8, w, h); OpenGLFuncs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, OpenGLLogicalScalingColor); OpenGLFuncs.glGenRenderbuffers(1, &OpenGLLogicalScalingDepth); OpenGLFuncs.glBindRenderbuffer(GL_RENDERBUFFER, OpenGLLogicalScalingDepth); @@ -4892,7 +4896,7 @@ InitializeOpenGLScaling(const int w, const int h) OpenGLFuncs.glBindFramebuffer(GL_FRAMEBUFFER, OpenGLLogicalScalingMultisampleFBO); OpenGLFuncs.glGenRenderbuffers(1, &OpenGLLogicalScalingMultisampleColor); OpenGLFuncs.glBindRenderbuffer(GL_RENDERBUFFER, OpenGLLogicalScalingMultisampleColor); - OpenGLFuncs.glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB8, w, h); + OpenGLFuncs.glRenderbufferStorage(GL_RENDERBUFFER, (alpha_size > 0) ? GL_RGBA8 : GL_RGB8, w, h); OpenGLFuncs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, OpenGLLogicalScalingMultisampleColor); OpenGLFuncs.glGenRenderbuffers(1, &OpenGLLogicalScalingMultisampleDepth); OpenGLFuncs.glBindRenderbuffer(GL_RENDERBUFFER, OpenGLLogicalScalingMultisampleDepth); @@ -5107,6 +5111,7 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12) SDL_assert(!VideoTexture20); /* either a new window or we destroyed all this */ SDL_assert(!VideoRenderer20); FIXME("Should we force a compatibility context here?"); + FIXME("If we're using logical scaling, we can turn off depth buffer, alpha, etc, since we'll make our own and only need an RGB color buffer for the window."); VideoGLContext20 = SDL20_GL_CreateContext(VideoWindow20); if (!VideoGLContext20) { return EndVidModeCreate(); From a6a965ab6262a3e88eba28a68bdc2753529244cd Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Fri, 3 Dec 2021 21:51:50 +0300 Subject: [PATCH 177/606] cleanup for build options --- CMakeLists.txt | 16 +++++++++------- src/Makefile.os2 | 6 ++++-- src/Makefile.w32 | 6 +++--- src/SDL12_compat.c | 2 +- src/SDL20_include_wrapper.h | 2 -- 5 files changed, 17 insertions(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2233a8b44..78c0dc4ba 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -66,12 +66,6 @@ endif() set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") string(STRIP "${CMAKE_C_FLAGS}" CMAKE_C_FLAGS) -# avoid DLL having 'lib' prefix with Windows MinGW builds -if(WIN32) - set(CMAKE_SHARED_LIBRARY_PREFIX "") - set_target_properties(SDL PROPERTIES COMPILE_DEFINITIONS "DLL_EXPORT") -endif() - if(UNIX AND NOT APPLE) set_target_properties(SDL PROPERTIES COMPILE_DEFINITIONS "_REENTRANT") target_link_libraries(SDL PRIVATE dl) @@ -90,8 +84,16 @@ elseif(UNIX AND NOT ANDROID) VERSION "${SDL12_COMPAT_VERSION_STR}" SOVERSION "0" OUTPUT_NAME "SDL-1.2") +elseif(WIN32) + # avoid DLL having 'lib' prefix with MinGW + set(CMAKE_SHARED_LIBRARY_PREFIX "") + set_target_properties(SDL PROPERTIES COMPILE_DEFINITIONS "DLL_EXPORT") + set_target_properties(SDL PROPERTIES + VERSION "${SDL12_COMPAT_VERSION_STR}" + SOVERSION "0" + OUTPUT_NAME "SDL") elseif(OS2) - # OS/2 version was built as SDL12.dll + set_target_properties(SDL PROPERTIES COMPILE_DEFINITIONS "BUILD_SDL") # for DECLSPEC set_target_properties(SDL PROPERTIES VERSION "${SDL12_COMPAT_VERSION_STR}" SOVERSION "0" diff --git a/src/Makefile.os2 b/src/Makefile.os2 index 9b8bdfd89..1f4080f0f 100644 --- a/src/Makefile.os2 +++ b/src/Makefile.os2 @@ -17,12 +17,14 @@ LIBFILE = $(LIBNAME).lib LNKFILE = $(LIBNAME).lnk CFLAGS_DEF=-bt=os2 -d0 -zq -bm -5s -fp5 -fpi87 -sg -oteanbmier $(INCPATH) -CFLAGS_DEF+= -DSDL_DISABLE_IMMINTRIN_H +CFLAGS_DEF+= -DNDEBUG -DSDL_DISABLE_IMMINTRIN_H +# for DECLSPEC +CFLAGS_DEF+= -DBUILD_SDL CFLAGS_DLL=$(CFLAGS_DEF) -bd # Special flags for building SDL CFLAGS=$(CFLAGS_DLL) -otexan -wx -ei -# avoid bogus W200 from cpuid code: +# avoid bogus W200 from cpuid code CFLAGS+= -wcd=200 # newer OpenWatcom versions enable W303 by default CFLAGS+= -wcd=303 diff --git a/src/Makefile.w32 b/src/Makefile.w32 index af1f65f2b..d85018ab6 100644 --- a/src/Makefile.w32 +++ b/src/Makefile.w32 @@ -17,14 +17,14 @@ LIBFILE = $(LIBNAME).lib LNKFILE = $(LIBNAME).lnk CFLAGS_DEF=-bt=nt -d0 -zq -bm -5s -fp5 -fpi87 -sg -oteanbmier $(INCPATH) -CFLAGS_DEF+= -DSDL_DISABLE_IMMINTRIN_H +CFLAGS_DEF+= -DNDEBUG -DSDL_DISABLE_IMMINTRIN_H # we override the DECLSPEC define in begin_code.h, because we are using # an exports file to remove the _cdecl '_' prefix from the symbol names -CFLAGS_DLL=$(CFLAGS_DEF) -bd -DDLL_EXPORT -DDECLSPEC= +CFLAGS_DLL=$(CFLAGS_DEF) -bd -DDECLSPEC= # Special flags for building SDL CFLAGS=$(CFLAGS_DLL) -otexan -wx -ei -# avoid bogus W200 from cpuid code: +# avoid bogus W200 from cpuid code CFLAGS+= -wcd=200 # newer OpenWatcom versions enable W303 by default CFLAGS+= -wcd=303 diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index e389c9e31..73f787962 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1246,7 +1246,7 @@ unsigned _System LibMain(unsigned hmod, unsigned termination) } #else - #error Please define your platform + #error Please define an init procedure for your platform. #endif #ifdef _WIN32 diff --git a/src/SDL20_include_wrapper.h b/src/SDL20_include_wrapper.h index 57d7ca5eb..eadf49732 100644 --- a/src/SDL20_include_wrapper.h +++ b/src/SDL20_include_wrapper.h @@ -101,8 +101,6 @@ #define SDL_RegisterApp IGNORE_THIS_VERSION_OF_SDL_RegisterApp #define SDL_UnregisterApp IGNORE_THIS_VERSION_OF_SDL_UnregisterApp -#define BUILD_SDL 1 - /* *** HACK HACK HACK: * *** Avoid including SDL_thread.h: it defines SDL_CreateThread() as a macro */ #if defined(_WIN32) || defined(__OS2__) From 911e9c223c89569703866f878b9fadc688c437e9 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 7 Dec 2021 10:22:17 -0500 Subject: [PATCH 178/606] windows: Deal with apps trying to force the "windib" video backend. Reference issue #8. --- src/SDL12_compat.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 73f787962..a1f877621 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1828,6 +1828,20 @@ SDL_InitSubSystem(Uint32 sdl12flags) Uint32 sdl20flags = 0; int rc; +#ifdef __WINDOWS__ + /* DOSBox (and probably other things), try to force the "windib" video + backend, but it doesn't exist in SDL2. Force to "windows" instead. */ + char *origenv = NULL; + const char *env = SDL20_getenv("SDL_VIDEODRIVER"); + if (env && (SDL20_strcmp(env, "windib") == 0)) { + origenv = SDL20_strdup(env); + if (origenv == NULL) { + return SDL20_OutOfMemory(); + } + SDL20_setenv("SDL_VIDEODRIVER", "windows", 1); + } +#endif + #ifdef __MACOSX__ extern void sdl12_compat_macos_init(void); sdl12_compat_macos_init(); @@ -1851,10 +1865,14 @@ SDL_InitSubSystem(Uint32 sdl12flags) rc = SDL20_Init(sdl20flags); if ((rc == 0) && (sdl20flags & SDL_INIT_VIDEO)) { if (Init12Video() < 0) { - return -1; + rc = -1; } } +#ifdef __WINDOWS__ + SDL20_free(origenv); +#endif + return rc; } From 9a6b2da17e5374865875e231613fffac0d3800b3 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 7 Dec 2021 10:44:32 -0500 Subject: [PATCH 179/606] windows: Make SDL_RegisterApp and SDL_UnregisterApp passthrough functions. Reference issue #8. --- src/SDL12_compat.c | 13 ------------- src/SDL20_syms.h | 5 +++++ 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index a1f877621..a7b9e2998 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1259,19 +1259,6 @@ SDL_SetModuleHandle(void *handle) { (void) handle;/* handled internally by SDL2 - nothing to do.. */ } - -/* FIXME: forward these two to the SDL2 versions ? */ -DECLSPEC int SDLCALL -SDL_RegisterApp(char *name, Uint32 style, void *hInst) -{ - (void) name; (void) style; (void) hInst; - return 0; -} - -DECLSPEC void SDLCALL -SDL_UnregisterApp(void) -{ -} #endif diff --git a/src/SDL20_syms.h b/src/SDL20_syms.h index 77cc48e69..1393217d8 100644 --- a/src/SDL20_syms.h +++ b/src/SDL20_syms.h @@ -328,6 +328,11 @@ SDL20_SYM(void,DestroyTexture,(SDL_Texture *a),(a),) SDL20_SYM(void,DestroyRenderer,(SDL_Renderer *a),(a),) SDL20_SYM(void,RenderPresent,(SDL_Renderer *a),(a),) +#ifdef _WIN32 +SDL20_SYM_PASSTHROUGH(int,RegisterApp,(const char *a, Uint32 b, void *c),(a,b,c),return) +SDL20_SYM_PASSTHROUGH(void,UnregisterApp,(void),(),) +#endif + /* These are optional OpenGL entry points for sdl12-compat's internal use. */ OPENGL_SYM(Core,const GLubyte *,glGetString,(GLenum a),(a),return) OPENGL_SYM(Core,GLenum,glGetError,(),(),return) From 8f3b53bed30fa2e77734130514277ec2fa29bf2a Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 7 Dec 2021 18:17:59 -0500 Subject: [PATCH 180/606] SDL_GL_GetAttribute: bind FBO 0 before querying SDL2. This appears to be an SDL2 bug; we are working around it. Fixes #150. --- src/SDL12_compat.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index a7b9e2998..adbe2d1f1 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -6471,6 +6471,8 @@ SDL_GL_SetAttribute(SDL12_GLattr attr, int value) DECLSPEC int SDLCALL SDL_GL_GetAttribute(SDL12_GLattr attr, int* value) { + int retval; + if (attr >= SDL12_GL_MAX_ATTRIBUTE) { return SDL20_SetError("Unknown GL attribute"); } @@ -6487,7 +6489,19 @@ SDL_GL_GetAttribute(SDL12_GLattr attr, int* value) *value = (OpenGLLogicalScalingSamples) ? 1 : 0; return 0; } - return SDL20_GL_GetAttribute((SDL_GLattr) attr, value); + + /* SDL2 has a bug where FBO 0 must be bound or SDL20_GL_GetAttribute gives incorrect information. + See https://github.com/libsdl-org/sdl12-compat/issues/150 */ + if (OpenGLCurrentDrawFBO == 0) { + retval = SDL20_GL_GetAttribute((SDL_GLattr) attr, value); + } else { + SDL_assert(OpenGLFuncs.glBindFramebuffer != NULL); + OpenGLFuncs.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + retval = SDL20_GL_GetAttribute((SDL_GLattr) attr, value); + OpenGLFuncs.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, OpenGLCurrentDrawFBO); + } + + return retval; } From b73b4e98484b110c5d4780a6f31e5d0e0962d47a Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 7 Dec 2021 23:44:02 -0500 Subject: [PATCH 181/606] windows: if we overrode "windib" envvar, set it back. Removed allocation here, too, because we don't need it. --- src/SDL12_compat.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index adbe2d1f1..8a0e9e791 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1818,13 +1818,10 @@ SDL_InitSubSystem(Uint32 sdl12flags) #ifdef __WINDOWS__ /* DOSBox (and probably other things), try to force the "windib" video backend, but it doesn't exist in SDL2. Force to "windows" instead. */ - char *origenv = NULL; + char *origvidenv = NULL; const char *env = SDL20_getenv("SDL_VIDEODRIVER"); if (env && (SDL20_strcmp(env, "windib") == 0)) { - origenv = SDL20_strdup(env); - if (origenv == NULL) { - return SDL20_OutOfMemory(); - } + origvidenv = "windib"; SDL20_setenv("SDL_VIDEODRIVER", "windows", 1); } #endif @@ -1857,7 +1854,9 @@ SDL_InitSubSystem(Uint32 sdl12flags) } #ifdef __WINDOWS__ - SDL20_free(origenv); + if (origvidenv) { /* set this back to minimize surprise state changes. */ + SDL20_setenv("SDL_VIDEODRIVER", origvidenv, 1); + } #endif return rc; From 29c825727e0ed9eba50b15ac66f1f3a0348f587e Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Wed, 8 Dec 2021 12:15:50 +0300 Subject: [PATCH 182/606] constify origenv --- src/SDL12_compat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 8a0e9e791..5411ee36e 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1818,7 +1818,7 @@ SDL_InitSubSystem(Uint32 sdl12flags) #ifdef __WINDOWS__ /* DOSBox (and probably other things), try to force the "windib" video backend, but it doesn't exist in SDL2. Force to "windows" instead. */ - char *origvidenv = NULL; + const char *origvidenv = NULL; const char *env = SDL20_getenv("SDL_VIDEODRIVER"); if (env && (SDL20_strcmp(env, "windib") == 0)) { origvidenv = "windib"; From 47e1fe0962e47f3caca88b240e4c48efb1cb220e Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Wed, 8 Dec 2021 12:25:20 +0300 Subject: [PATCH 183/606] CI: switch to SDL2 release-2.0.18 --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index f46387b9e..1552ec640 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -24,7 +24,7 @@ jobs: uses: actions/checkout@v2 with: repository: libsdl-org/SDL - ref: release-2.0.14 + ref: release-2.0.18 path: SDL2 - name: Configure CMake run: cmake -DSDL2_INCLUDE_DIR="${{ github.workspace }}/SDL2/include" -B build ${{ matrix.platform.flags }} From d71c89535f3d8bf9a3f0829f52b26d13c7c6c5f7 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Wed, 8 Dec 2021 17:01:20 +0300 Subject: [PATCH 184/606] headers: fix SDL_atoi() --- include/SDL/SDL_stdinc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/SDL/SDL_stdinc.h b/include/SDL/SDL_stdinc.h index a6e364acf..aa070c4cb 100644 --- a/include/SDL/SDL_stdinc.h +++ b/include/SDL/SDL_stdinc.h @@ -410,7 +410,7 @@ extern DECLSPEC int SDLCALL SDL_vsnprintf(char *text, size_t maxlen, const char #define SDL_itoa(value, string, radix) SDL_ltoa((long)value, string, radix) #define SDL_uitoa(value, string, radix) SDL_ultoa((long)value, string, radix) -#define SDL_atoi(X) SDL_strtol(X, NULL, 0) +#define SDL_atoi(X) SDL_strtol(X, NULL, 10) #define SDL_atof(X) SDL_strtod(X, NULL) #define SDL_ICONV_ERROR (size_t)-1 From 677137dcc75d1312f94cdf7b25175442c7328e96 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 9 Dec 2021 09:04:30 -0500 Subject: [PATCH 185/606] cmake: Remove "MACOSX_RPATH 1" setting. Fixes #87. --- CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 78c0dc4ba..c40434341 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -76,7 +76,6 @@ if(APPLE) "-Wl,-compatibility_version,${DYLIB_COMPAT_VERSION} -Wl,-current_version,${DYLIB_CURRENT_VERSION}") target_link_libraries(SDL PRIVATE "-framework AppKit") set_target_properties(SDL PROPERTIES - MACOSX_RPATH 1 OUTPUT_NAME "SDL-1.2.0" ) elseif(UNIX AND NOT ANDROID) From 87433054970f14660d8713e1352b448817905391 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 9 Dec 2021 09:28:14 -0500 Subject: [PATCH 186/606] cmake: attempt to quell CMP0068 warnings. --- CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index c40434341..2184809d8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -38,6 +38,11 @@ set(SDL12COMPAT_SRCS ) add_library(SDL SHARED ${SDL12COMPAT_SRCS}) +if(APPLE) + set_target_properties(SDL PROPERTIES INSTALL_NAME_DIR "") +endif() + + include(CheckCSourceCompiles) include(CheckIncludeFile) include(CheckCCompilerFlag) From 6f59aa8ee0a96b533354372ffc19fd1b053edf2a Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sat, 11 Dec 2021 10:32:02 +0300 Subject: [PATCH 187/606] update to dr_mp3.h from mainstream. --- src/dr_mp3.h | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/dr_mp3.h b/src/dr_mp3.h index 56344ad2e..dad327cc1 100644 --- a/src/dr_mp3.h +++ b/src/dr_mp3.h @@ -1,6 +1,6 @@ /* MP3 audio decoder. Choice of public domain or MIT-0. See license statements at the end of this file. -dr_mp3 - v0.6.31 - 2021-08-22 +dr_mp3 - v0.6.32 - 2021-12-11 David Reid - mackron@gmail.com @@ -101,7 +101,7 @@ extern "C" { #define DRMP3_VERSION_MAJOR 0 #define DRMP3_VERSION_MINOR 6 -#define DRMP3_VERSION_REVISION 31 +#define DRMP3_VERSION_REVISION 32 #define DRMP3_VERSION_STRING DRMP3_XSTRINGIFY(DRMP3_VERSION_MAJOR) "." DRMP3_XSTRINGIFY(DRMP3_VERSION_MINOR) "." DRMP3_XSTRINGIFY(DRMP3_VERSION_REVISION) #include /* For size_t. */ @@ -113,7 +113,7 @@ typedef signed short drmp3_int16; typedef unsigned short drmp3_uint16; typedef signed int drmp3_int32; typedef unsigned int drmp3_uint32; -#if defined(_MSC_VER) +#if defined(_MSC_VER) && !defined(__clang__) typedef signed __int64 drmp3_int64; typedef unsigned __int64 drmp3_uint64; #else @@ -4502,6 +4502,9 @@ counts rather than sample counts. /* REVISION HISTORY ================ +v0.6.32 - 2021-12-11 + - Fix a warning with Clang. + v0.6.31 - 2021-08-22 - Fix a bug when loading from memory. From 2ddfc6b436e9d306bbe27e9753d0ffdb0a12aca8 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sat, 11 Dec 2021 17:46:27 -0500 Subject: [PATCH 188/606] cmake: Select NEW policy for CMP0068. (on macOS, don't let RPATH affect install_name.) Fixes #151. --- CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2184809d8..948eda3e5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,6 +7,8 @@ project(sdl12_compat VERSION 0.0.1 LANGUAGES C) +cmake_policy(SET CMP0068 NEW) # on macOS, don't let RPATH affect install_name. + set(SDL12_COMPAT_VERSION_STR "1.2.50") option(SDL12TESTS "Enable to build SDL-1.2 test programs" ON) From 74b56a846116c912ca0c113d9b1be5d9e9a1eace Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sun, 12 Dec 2021 03:11:20 +0300 Subject: [PATCH 189/606] compatibility with cmake < 3.9 --- CMakeLists.txt | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 948eda3e5..f4e0779c2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,8 +7,6 @@ project(sdl12_compat VERSION 0.0.1 LANGUAGES C) -cmake_policy(SET CMP0068 NEW) # on macOS, don't let RPATH affect install_name. - set(SDL12_COMPAT_VERSION_STR "1.2.50") option(SDL12TESTS "Enable to build SDL-1.2 test programs" ON) @@ -28,7 +26,12 @@ if(APPLE) set(DYLIB_COMPAT_VERSION 1.0.0 CACHE STRING "library compatibility version") set(DYLIB_CURRENT_VERSION 12.50.0 CACHE STRING "library current version") include_directories("/opt/X11/include") # hack. + if(CMAKE_VERSION VERSION_LESS 3.9) + else() + cmake_policy(SET CMP0068 NEW) # on macOS, don't let RPATH affect install_name. + endif() endif() + if(WIN32) set(WIN32_SRCS "src/version.rc") endif() @@ -40,11 +43,6 @@ set(SDL12COMPAT_SRCS ) add_library(SDL SHARED ${SDL12COMPAT_SRCS}) -if(APPLE) - set_target_properties(SDL PROPERTIES INSTALL_NAME_DIR "") -endif() - - include(CheckCSourceCompiles) include(CheckIncludeFile) include(CheckCCompilerFlag) @@ -78,6 +76,7 @@ if(UNIX AND NOT APPLE) target_link_libraries(SDL PRIVATE dl) endif() if(APPLE) + set_target_properties(SDL PROPERTIES INSTALL_NAME_DIR "") set_target_properties(SDL PROPERTIES COMPILE_DEFINITIONS "_THREAD_SAFE") set_target_properties(SDL PROPERTIES LINK_FLAGS "-Wl,-compatibility_version,${DYLIB_COMPAT_VERSION} -Wl,-current_version,${DYLIB_CURRENT_VERSION}") From 5b92209cbd1a49b4ff4c60e1f2e445a8e65fc776 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 13 Dec 2021 09:02:32 -0500 Subject: [PATCH 190/606] docs: Added initial work on a document on game-specific compatibility. Reference issue #147. --- COMPATIBILITY.md | 49 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 COMPATIBILITY.md diff --git a/COMPATIBILITY.md b/COMPATIBILITY.md new file mode 100644 index 000000000..b8796216d --- /dev/null +++ b/COMPATIBILITY.md @@ -0,0 +1,49 @@ +# Compatibility notes + +This is a list of quirks and known-issues for specific games, with possible +workarounds. + +We are currently building and maintaining a list of all known SDL 1.2 games +and their current state with sdl12-compat over here: + +https://docs.google.com/spreadsheets/d/1u8Rq3LVQYYgu28sBuxrZ371QolbiZu5z_LjENc4ddZs/edit?usp=sharing + + + +## Dynamite Jack (Linux) + +More modern builds are ported to SDL2, but the older 1.2 binaries will work +on X11 if you turn off OpenGL Scaling + + export SDL12COMPAT_OPENGL_SCALING=0 + +Note that this game calls glXGetProcAddress() directly and likely will not +work as a native Wayland app (XWayland works fine, however). + + +## Hammerfight (Linux) + +You probably aren't getting usable mouse input, as the game talks directly to +XInput2 on X11 (and tries to use /dev/input if that fails). This is not an +sdl12-compat bug, as this is going outside of SDL to get multiple mice +input. The game is statically linked to a copy of [ManyMouse](https://icculus.org/manymouse/), +which provides multiple mice access. + + +The simplest way to deal with this is change this line in the game's +Config.ini file: + + CORE_INIT_RI=true + +Make that false and it won't even try to initialize ManyMouse, and will use +standard SDL 1.2 mouse events for single-player input. (The "RI" stands for +"RawInput," which Hammerfight uses on Windows for multi-mice support). + +Of course, with this change, you can't have multiple players on the same +machine using separate mice. + +That game dlopen()'s the XInput2 libraries instead of linking to them +directly, so this does not prevent the game from working on Wayland. No +XWayland needed! + + From f3ddb3d477b6c3c401999db9f35f3e9064a257d3 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sat, 11 Dec 2021 13:12:22 -0500 Subject: [PATCH 191/606] macos: Don't override -[NSApplication terminate], use the delegate instead. Reference issue #106. --- src/SDLmain/macosx/SDLMain.m | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/SDLmain/macosx/SDLMain.m b/src/SDLmain/macosx/SDLMain.m index 07d392eef..2b4663202 100644 --- a/src/SDLmain/macosx/SDLMain.m +++ b/src/SDLmain/macosx/SDLMain.m @@ -64,22 +64,17 @@ - (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString; @end #endif -@interface NSApplication (SDLApplication) -@end +/* The main class of the application, the application's delegate */ +@implementation SDLMain -@implementation NSApplication (SDLApplication) -/* Invoked from the Quit menu item */ -- (void)terminate:(id)sender +- (NSApplicationTerminateReply) applicationShouldTerminate:(NSApplication *)sender { /* Post a SDL_QUIT event */ SDL_Event event; event.type = SDL_QUIT; SDL_PushEvent(&event); + return NSTerminateCancel; } -@end - -/* The main class of the application, the application's delegate */ -@implementation SDLMain /* Set the working directory to the .app's parent directory */ - (void) setupWorkingDirectory:(BOOL)shouldChdir From fee41894186261954c019495244ddcfe79ad3658 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sat, 11 Dec 2021 13:36:01 -0500 Subject: [PATCH 192/606] macos: Replace deprecated NSAlternateKeyMask. --- src/SDLmain/macosx/SDLMain.m | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/SDLmain/macosx/SDLMain.m b/src/SDLmain/macosx/SDLMain.m index 2b4663202..673f89d80 100644 --- a/src/SDLmain/macosx/SDLMain.m +++ b/src/SDLmain/macosx/SDLMain.m @@ -17,6 +17,9 @@ @interface NSApplication(SDL_Missing_Methods) - (void)setAppleMenu:(NSMenu *)menu; @end +/* NSEventModifierFlagOption replaced NSAlternateKeyMask in 10.12, but it's the same value. */ +#define EventModifierFlagOption (1 << 19) + /* Use this flag to determine whether we use SDLMain.nib or not */ #define SDL_USE_NIB_FILE 0 @@ -139,7 +142,7 @@ static void setApplicationMenu(void) [appleMenu addItemWithTitle:title action:@selector(hide:) keyEquivalent:@"h"]; menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"]; - [menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)]; + [menuItem setKeyEquivalentModifierMask:(EventModifierFlagOption|NSCommandKeyMask)]; [appleMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""]; From 328985f8e8fd589a3898977099908d6111e78ca5 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sat, 11 Dec 2021 13:42:32 -0500 Subject: [PATCH 193/606] macos: Replace NSCommandKeyMask with NSEventModifierFlagCommand, too. Reference issue #106. --- src/SDLmain/macosx/SDLMain.m | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/SDLmain/macosx/SDLMain.m b/src/SDLmain/macosx/SDLMain.m index 673f89d80..677ccb02e 100644 --- a/src/SDLmain/macosx/SDLMain.m +++ b/src/SDLmain/macosx/SDLMain.m @@ -19,6 +19,8 @@ - (void)setAppleMenu:(NSMenu *)menu; /* NSEventModifierFlagOption replaced NSAlternateKeyMask in 10.12, but it's the same value. */ #define EventModifierFlagOption (1 << 19) +/* Same deal with the NSCommandKeyMask... */ +#define EventModifierFlagCommand (1 << 20) /* Use this flag to determine whether we use SDLMain.nib or not */ #define SDL_USE_NIB_FILE 0 @@ -142,7 +144,7 @@ static void setApplicationMenu(void) [appleMenu addItemWithTitle:title action:@selector(hide:) keyEquivalent:@"h"]; menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"]; - [menuItem setKeyEquivalentModifierMask:(EventModifierFlagOption|NSCommandKeyMask)]; + [menuItem setKeyEquivalentModifierMask:(EventModifierFlagOption|EventModifierFlagCommand)]; [appleMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""]; From efd136625bcc51aa8c5450737e99aff2c2e681b0 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sat, 11 Dec 2021 14:08:39 -0500 Subject: [PATCH 194/606] macos: Subclass SDLMain from NSApplicationDelegate, move some stuff. Reference Issue #106. --- src/SDLmain/macosx/SDLMain.h | 18 +++++++++++++++++- src/SDLmain/macosx/SDLMain.m | 5 ----- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/SDLmain/macosx/SDLMain.h b/src/SDLmain/macosx/SDLMain.h index c56d90cbe..3dfee70a2 100644 --- a/src/SDLmain/macosx/SDLMain.h +++ b/src/SDLmain/macosx/SDLMain.h @@ -10,7 +10,23 @@ #import -@interface SDLMain : NSObject +/* Note that the following defines have not been changed in a long time and + it's likely going to need fixes if you try it. */ + +/* Use this flag to determine whether we use SDLMain.nib or not */ +#define SDL_USE_NIB_FILE 0 + +/* Use this flag to determine whether we use CPS (docking) or not */ +#define SDL_USE_CPS 1 + +@interface SDLMain : NSApplicationDelegate +- (NSApplicationTerminateReply) applicationShouldTerminate:(NSApplication *)sender; +- (void) setupWorkingDirectory:(BOOL)shouldChdir; +- (BOOL) application:(NSApplication *)theApplication openFile:(NSString *)filename +- (void) applicationDidFinishLaunching: (NSNotification *) note +#if SDL_USE_NIB_FILE +- (void)fixMenu:(NSMenu *)aMenu withAppName:(NSString *)appName +#endif @end #endif /* _SDLMain_h_ */ diff --git a/src/SDLmain/macosx/SDLMain.m b/src/SDLmain/macosx/SDLMain.m index 677ccb02e..7b4899526 100644 --- a/src/SDLmain/macosx/SDLMain.m +++ b/src/SDLmain/macosx/SDLMain.m @@ -22,11 +22,6 @@ - (void)setAppleMenu:(NSMenu *)menu; /* Same deal with the NSCommandKeyMask... */ #define EventModifierFlagCommand (1 << 20) -/* Use this flag to determine whether we use SDLMain.nib or not */ -#define SDL_USE_NIB_FILE 0 - -/* Use this flag to determine whether we use CPS (docking) or not */ -#define SDL_USE_CPS 1 #ifdef SDL_USE_CPS /* Portions of CPS.h */ typedef struct CPSProcessSerNum From 4ad3fd3f2805e077f36ecc71971c14f266e01343 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sat, 11 Dec 2021 14:40:20 -0500 Subject: [PATCH 195/606] macos: Patched to compile. Reference issue #106. --- src/SDLmain/macosx/SDLMain.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/SDLmain/macosx/SDLMain.h b/src/SDLmain/macosx/SDLMain.h index 3dfee70a2..4acb2ada6 100644 --- a/src/SDLmain/macosx/SDLMain.h +++ b/src/SDLmain/macosx/SDLMain.h @@ -19,13 +19,13 @@ /* Use this flag to determine whether we use CPS (docking) or not */ #define SDL_USE_CPS 1 -@interface SDLMain : NSApplicationDelegate +@interface SDLMain : NSObject - (NSApplicationTerminateReply) applicationShouldTerminate:(NSApplication *)sender; - (void) setupWorkingDirectory:(BOOL)shouldChdir; -- (BOOL) application:(NSApplication *)theApplication openFile:(NSString *)filename -- (void) applicationDidFinishLaunching: (NSNotification *) note +- (BOOL) application:(NSApplication *)theApplication openFile:(NSString *)filename; +- (void) applicationDidFinishLaunching: (NSNotification *) note; #if SDL_USE_NIB_FILE -- (void)fixMenu:(NSMenu *)aMenu withAppName:(NSString *)appName +- (void)fixMenu:(NSMenu *)aMenu withAppName:(NSString *)appName; #endif @end From 20d5f4a44db387f6c722713cab4cea58c362807f Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sat, 11 Dec 2021 16:58:07 -0500 Subject: [PATCH 196/606] macos: Remove deprecated SDL_USE_CPS code. This pulls in a more modern idea from SDL2, but hasn't been tested. (just using the buildbot to make sure it compiles in this commit). Reference issue #106. --- src/SDLmain/macosx/SDLMain.h | 3 --- src/SDLmain/macosx/SDLMain.m | 37 +++++++++++------------------------- 2 files changed, 11 insertions(+), 29 deletions(-) diff --git a/src/SDLmain/macosx/SDLMain.h b/src/SDLmain/macosx/SDLMain.h index 4acb2ada6..f6ea978b4 100644 --- a/src/SDLmain/macosx/SDLMain.h +++ b/src/SDLmain/macosx/SDLMain.h @@ -16,9 +16,6 @@ /* Use this flag to determine whether we use SDLMain.nib or not */ #define SDL_USE_NIB_FILE 0 -/* Use this flag to determine whether we use CPS (docking) or not */ -#define SDL_USE_CPS 1 - @interface SDLMain : NSObject - (NSApplicationTerminateReply) applicationShouldTerminate:(NSApplication *)sender; - (void) setupWorkingDirectory:(BOOL)shouldChdir; diff --git a/src/SDLmain/macosx/SDLMain.m b/src/SDLmain/macosx/SDLMain.m index 7b4899526..4c9f720a8 100644 --- a/src/SDLmain/macosx/SDLMain.m +++ b/src/SDLmain/macosx/SDLMain.m @@ -22,19 +22,6 @@ - (void)setAppleMenu:(NSMenu *)menu; /* Same deal with the NSCommandKeyMask... */ #define EventModifierFlagCommand (1 << 20) -#ifdef SDL_USE_CPS -/* Portions of CPS.h */ -typedef struct CPSProcessSerNum -{ - UInt32 lo; - UInt32 hi; -} CPSProcessSerNum; - -extern OSErr CPSGetCurrentProcess( CPSProcessSerNum *psn); -extern OSErr CPSEnableForegroundOperation( CPSProcessSerNum *psn, UInt32 _arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5); -extern OSErr CPSSetFrontProcess( CPSProcessSerNum *psn); - -#endif /* SDL_USE_CPS */ static int gArgc; static char **gArgv; @@ -195,19 +182,9 @@ static void CustomApplicationMain (int argc, char **argv) NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; SDLMain *sdlMain; - /* Ensure the application object is initialised */ - [NSApplication sharedApplication]; - -#ifdef SDL_USE_CPS - { - CPSProcessSerNum PSN; - /* Tell the dock about us */ - if (!CPSGetCurrentProcess(&PSN)) - if (!CPSEnableForegroundOperation(&PSN,0x03,0x3C,0x2C,0x1103)) - if (!CPSSetFrontProcess(&PSN)) - [NSApplication sharedApplication]; - } -#endif /* SDL_USE_CPS */ + /* Ensure the application object is initialised and converted to a GUI app if necessary. */ + ProcessSerialNumber psn = { 0, kCurrentProcess}; + TransformProcessType(&psn, kProcessTransformToForegroundApplication); /* Set up the menubar */ [NSApp setMainMenu:[[NSMenu alloc] init]]; @@ -282,6 +259,14 @@ - (void) applicationDidFinishLaunching: (NSNotification *) note { int status; + /* Get more aggressive about activation for Catalina and later: activate the Dock first so we definitely reset all activation state. */ + for (NSRunningApplication *i in [NSRunningApplication runningApplicationsWithBundleIdentifier:@"com.apple.dock"]) { + [i activateWithOptions:NSApplicationActivateIgnoringOtherApps]; + break; + } + SDL_Delay(300); /* !!! FIXME: this isn't right. */ + [NSApp activateIgnoringOtherApps:YES]; + /* Set the working directory to the .app's parent directory */ [self setupWorkingDirectory:gFinderLaunch]; From 8041d0fbe9c76b5bf717e28320e6b9bc0309245b Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 13 Dec 2021 22:51:35 -0500 Subject: [PATCH 197/606] macos: Whoops, we need to intialize NSApp before using it in SDLmain. --- src/SDLmain/macosx/SDLMain.m | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/SDLmain/macosx/SDLMain.m b/src/SDLmain/macosx/SDLMain.m index 4c9f720a8..a899beb9b 100644 --- a/src/SDLmain/macosx/SDLMain.m +++ b/src/SDLmain/macosx/SDLMain.m @@ -186,6 +186,9 @@ static void CustomApplicationMain (int argc, char **argv) ProcessSerialNumber psn = { 0, kCurrentProcess}; TransformProcessType(&psn, kProcessTransformToForegroundApplication); + /* Ensure the application object is initialised */ + [NSApplication sharedApplication]; + /* Set up the menubar */ [NSApp setMainMenu:[[NSMenu alloc] init]]; setApplicationMenu(); From 1e057ad82866a043b7c322e9efe360e382bb07d2 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 13 Dec 2021 23:04:27 -0500 Subject: [PATCH 198/606] macos: Don't need this in 1.2 SDLmain; SDL2 does this for us. --- src/SDLmain/macosx/SDLMain.m | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/SDLmain/macosx/SDLMain.m b/src/SDLmain/macosx/SDLMain.m index a899beb9b..0b444e77b 100644 --- a/src/SDLmain/macosx/SDLMain.m +++ b/src/SDLmain/macosx/SDLMain.m @@ -262,14 +262,6 @@ - (void) applicationDidFinishLaunching: (NSNotification *) note { int status; - /* Get more aggressive about activation for Catalina and later: activate the Dock first so we definitely reset all activation state. */ - for (NSRunningApplication *i in [NSRunningApplication runningApplicationsWithBundleIdentifier:@"com.apple.dock"]) { - [i activateWithOptions:NSApplicationActivateIgnoringOtherApps]; - break; - } - SDL_Delay(300); /* !!! FIXME: this isn't right. */ - [NSApp activateIgnoringOtherApps:YES]; - /* Set the working directory to the .app's parent directory */ [self setupWorkingDirectory:gFinderLaunch]; From 8f54fd8010551ef358eb5f5a22d294794b5e984f Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 14 Dec 2021 21:29:04 -0500 Subject: [PATCH 199/606] audio: Fixed undefined silence value in SDL_OpenAudio(). This gets rid of the popping sound in DOSBox, etc. Fixes #122. --- src/SDL12_compat.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 5411ee36e..a291837f1 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -7888,6 +7888,9 @@ OpenSDL2AudioDevice(SDL_AudioSpec *want) want->userdata = orig_userdata; want->size = want->samples * want->channels * (SDL_AUDIO_BITSIZE(want->format) / 8); + /* note that 0x80 isn't perfect silence for U16 formats, but we only have one byte that is used for memset() calls, so it has to do. SDL2 has the same bug. */ + want->silence = SDL_AUDIO_ISSIGNED(want->format) ? 0x00 : 0x80; + /* reset audiostreams if device format changed. */ FIXME("deal with failure in here"); ResetAudioStreamForDeviceChange(&audio_cbdata->app_callback_stream, &audio_cbdata->app_callback_format); From d01bc97f5c025b2b8285242524853af77f344598 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 16 Dec 2021 00:21:43 -0500 Subject: [PATCH 200/606] api: Implement X11_KeyToUnicode. This is for compat with some existing games that touched an internal piece of SDL; it was not part of the public 1.2 API. This is an _extremely_ naive implementation of this function, but I'm hoping it's good enough for the few things that use it. Patches that don't make this function ridiculous are welcome, though. Fixes #153. --- src/SDL12_compat.c | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index a291837f1..83cd40b7c 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -57,8 +57,6 @@ #undef snprintf #undef vsnprintf -/* !!! IMPLEMENT_ME X11_KeyToUnicode ? */ - #define SDL_BlitSurface SDL_UpperBlit #ifdef __cplusplus @@ -8095,6 +8093,35 @@ SDL_GL_EnableContext_Thread(void) SDL20_GL_MakeCurrent(enable ? VideoWindow20 : NULL, enable ? VideoGLContext20 : NULL); } + +/* X11_KeyToUnicode is an internal function in the SDL 1.2 x11 backend that some Linux + software (older versions of the Torque Engine, for example) would call directly, so + we're supplying an extremely naive implementation here. Apps using this should be + fixed if possible, and this implementation is generally incorrect but hopefully + enough to get apps to limp along. + As this isn't X11-specific, we supply it globally, so x11 binaries can transition + to Wayland, and if there's some wildly-misbuilt win32 software, they can call it + too. :) */ + +DECLSPEC Uint16 SDLCALL +X11_KeyToUnicode(SDL12Key key, SDL12Mod mod) +{ + if (((int) key) >= 127) { + return 0; + } else if ((key >= SDLK12_0) && (key <= SDLK12_9)) { + return (Uint16) ('0' + (key - SDLK12_0)); + } else if ((key >= SDLK12_a) && (key <= SDLK12_z)) { + const int shifted = ((mod & (KMOD12_LSHIFT|KMOD12_RSHIFT)) != 0) ? 1 : 0; + int capital = ((mod & KMOD12_CAPS) != 0) ? 1 : 0; + if (shifted) { + capital = !capital; + } + return (Uint16) ((capital ? 'A' : 'a') + (key - SDLK12_a)); + } + + return (Uint16) key; +} + #ifdef __cplusplus } #endif From 8d2220f42893d7297098c1cd8677d0dc8c65ea7e Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 16 Dec 2021 00:34:05 -0500 Subject: [PATCH 201/606] X11_KeyToUnicode: No need to tapdance for numbers, they match ASCII values. Reference issue #153. --- src/SDL12_compat.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 83cd40b7c..6647bc791 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -8108,8 +8108,6 @@ X11_KeyToUnicode(SDL12Key key, SDL12Mod mod) { if (((int) key) >= 127) { return 0; - } else if ((key >= SDLK12_0) && (key <= SDLK12_9)) { - return (Uint16) ('0' + (key - SDLK12_0)); } else if ((key >= SDLK12_a) && (key <= SDLK12_z)) { const int shifted = ((mod & (KMOD12_LSHIFT|KMOD12_RSHIFT)) != 0) ? 1 : 0; int capital = ((mod & KMOD12_CAPS) != 0) ? 1 : 0; From d05899f95c5d7e7e2d8eee40ddf3815e53a3bddf Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Thu, 16 Dec 2021 14:00:32 +0300 Subject: [PATCH 202/606] Restrict X11_KeyToUnicode to unix builds. Reference issue #153. --- src/SDL12_compat.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 6647bc791..ef62faa67 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -8102,13 +8102,14 @@ SDL_GL_EnableContext_Thread(void) As this isn't X11-specific, we supply it globally, so x11 binaries can transition to Wayland, and if there's some wildly-misbuilt win32 software, they can call it too. :) */ - +#if !(defined(_WIN32) || defined(__OS2__)) /* #if defined(__unix__) || defined(__APPLE__) ?? */ DECLSPEC Uint16 SDLCALL X11_KeyToUnicode(SDL12Key key, SDL12Mod mod) { if (((int) key) >= 127) { return 0; - } else if ((key >= SDLK12_a) && (key <= SDLK12_z)) { + } + if ((key >= SDLK12_a) && (key <= SDLK12_z)) { const int shifted = ((mod & (KMOD12_LSHIFT|KMOD12_RSHIFT)) != 0) ? 1 : 0; int capital = ((mod & KMOD12_CAPS) != 0) ? 1 : 0; if (shifted) { @@ -8119,6 +8120,7 @@ X11_KeyToUnicode(SDL12Key key, SDL12Mod mod) return (Uint16) key; } +#endif #ifdef __cplusplus } From b0e6fa1cc643b6c57563ac581f40278a7c367291 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Tue, 18 Jan 2022 14:31:40 +0300 Subject: [PATCH 203/606] updates for watcom optimization flags --- src/Makefile.os2 | 19 +++++++++++-------- src/Makefile.w32 | 20 ++++++++++++-------- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/src/Makefile.os2 b/src/Makefile.os2 index 1f4080f0f..ca832ad65 100644 --- a/src/Makefile.os2 +++ b/src/Makefile.os2 @@ -16,18 +16,21 @@ DLLFILE = $(LIBNAME).dll LIBFILE = $(LIBNAME).lib LNKFILE = $(LIBNAME).lnk -CFLAGS_DEF=-bt=os2 -d0 -zq -bm -5s -fp5 -fpi87 -sg -oteanbmier $(INCPATH) -CFLAGS_DEF+= -DNDEBUG -DSDL_DISABLE_IMMINTRIN_H -# for DECLSPEC -CFLAGS_DEF+= -DBUILD_SDL -CFLAGS_DLL=$(CFLAGS_DEF) -bd - -# Special flags for building SDL -CFLAGS=$(CFLAGS_DLL) -otexan -wx -ei +CFLAGS = -bt=os2 -d0 -zq -bm -5s -fp5 -fpi87 -sg -oeatxhn -ei +# max warnings: +CFLAGS+= -wx # avoid bogus W200 from cpuid code CFLAGS+= -wcd=200 # newer OpenWatcom versions enable W303 by default CFLAGS+= -wcd=303 +# the include paths : +CFLAGS+= $(INCPATH) +# building dll: +CFLAGS+= -bd +# for DECLSPEC +CFLAGS+= -DBUILD_SDL +# misc +CFLAGS+= -DNDEBUG -DSDL_DISABLE_IMMINTRIN_H DESCRIPTION = Simple DirectMedia Layer 1.2 diff --git a/src/Makefile.w32 b/src/Makefile.w32 index d85018ab6..543e0787f 100644 --- a/src/Makefile.w32 +++ b/src/Makefile.w32 @@ -16,18 +16,22 @@ DLLFILE = $(LIBNAME).dll LIBFILE = $(LIBNAME).lib LNKFILE = $(LIBNAME).lnk -CFLAGS_DEF=-bt=nt -d0 -zq -bm -5s -fp5 -fpi87 -sg -oteanbmier $(INCPATH) -CFLAGS_DEF+= -DNDEBUG -DSDL_DISABLE_IMMINTRIN_H -# we override the DECLSPEC define in begin_code.h, because we are using -# an exports file to remove the _cdecl '_' prefix from the symbol names -CFLAGS_DLL=$(CFLAGS_DEF) -bd -DDECLSPEC= - -# Special flags for building SDL -CFLAGS=$(CFLAGS_DLL) -otexan -wx -ei +CFLAGS =-bt=nt -d0 -zq -bm -5s -fp5 -fpi87 -sg -oeatxhn -ei +# max warnings: +CFLAGS+= -wx # avoid bogus W200 from cpuid code CFLAGS+= -wcd=200 # newer OpenWatcom versions enable W303 by default CFLAGS+= -wcd=303 +# the include paths : +CFLAGS+= $(INCPATH) +# building dll: +CFLAGS+= -bd +# we override the DECLSPEC define in begin_code.h, because we are using +# an exports file to remove the _cdecl '_' prefix from the symbol names +CFLAGS+= -DDECLSPEC= +# misc +CFLAGS+= -DNDEBUG -DSDL_DISABLE_IMMINTRIN_H object_files= SDL12_compat.obj resource_obj= version.res From 4acdd2bef37ebff235a20a5d7b2b6715e139bf00 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 24 Jan 2022 09:55:10 -0500 Subject: [PATCH 204/606] events: Don't send an SDL_QUIT for SDL_WINDOWEVENT_CLOSE. Otherwise, since 1.2 only ever has one windows, we just end up sending two SDL12_QUIT events, which confuses TuxPaint. It's better to look for the SDL_QUIT event anyhow, since SIGINT on Unix, Command-Q on macOS, etc, can trigger it, too. Fixes #154. --- src/SDL12_compat.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index ef62faa67..57c0ed0d7 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -3665,9 +3665,9 @@ EventFilter20to12(void *data, SDL_Event *event20) case SDL_WINDOWEVENT: switch (event20->window.event) { - case SDL_WINDOWEVENT_CLOSE: - event12.type = SDL12_QUIT; - break; + /* don't send an SDL12_QUIT event for SDL_WINDOWEVENT_CLOSE; + we only ever have a single window, so an SDL_QUIT will be + coming from SDL2 next anyhow, so just send that on. */ case SDL_WINDOWEVENT_SHOWN: case SDL_WINDOWEVENT_EXPOSED: From 719c65247b82b0ce62b87194cb8b8ed01eaa3196 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 24 Jan 2022 13:47:30 -0500 Subject: [PATCH 205/606] cdrom: Fixed closing of CD-ROM device while it's still playing. Fixes #32. --- src/SDL12_compat.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 57c0ed0d7..26bdc4893 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -7677,6 +7677,7 @@ SDL_CDClose(SDL12_CD *cdrom) SDL20_LockAudio(); if (audio_cbdata) { + audio_cbdata->cdrom_status = SDL12_CD_STOPPED; audio_cbdata->cdrom_opened = SDL_FALSE; } SDL20_UnlockAudio(); From 63406f52612066e3bf00e90c96e1f3502cf561a2 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 24 Jan 2022 16:10:56 -0500 Subject: [PATCH 206/606] Remove a FIXME for screensaver setup. Turns out SDL2 already checks the same environment variable (as an SDL2 hint, specifically), so we don't have to manage this in sdl12-compat. Reference issue #143. --- src/SDL12_compat.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 26bdc4893..2263166fe 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -5260,8 +5260,6 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12) HandleInputGrab(SDL12_GRAB_ON); } - FIXME("setup screen saver"); - VideoSurfacePresentTicks = 0; VideoSurfaceLastPresentTicks = 0; From d76fd2c1862e51ad0b1d856d0e39efd2cbf7895b Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 24 Jan 2022 16:17:51 -0500 Subject: [PATCH 207/606] Remove unused SetupScreenSaver function. Reference Issue #143. --- src/SDL12_compat.c | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 2263166fe..4a2483bc9 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -4594,30 +4594,6 @@ GetEnvironmentWindowPosition(int *x, int *y) } } -#if 0 /* unused, yet. */ -static void -SetupScreenSaver(const int flags12) -{ - const char *env; - SDL_bool allow_screensaver; - - /* Allow environment override of screensaver disable */ - env = SDL20_getenv("SDL_VIDEO_ALLOW_SCREENSAVER"); - if (env) { - allow_screensaver = SDL20_atoi(env) ? SDL_TRUE : SDL_FALSE; - } else if (flags12 & SDL12_FULLSCREEN) { - allow_screensaver = SDL_FALSE; - } else { - allow_screensaver = SDL_TRUE; - } - if (allow_screensaver) { - SDL20_EnableScreenSaver(); - } else { - SDL20_DisableScreenSaver(); - } -} -#endif - static SDL12_Surface * EndVidModeCreate(void) { From fc6a03ea75430b3c6fe991eb268edb9cbf1d1744 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 24 Jan 2022 23:55:31 -0500 Subject: [PATCH 208/606] SDL_VideoInit() should call Init12Video() Reference Issue #143. --- src/SDL12_compat.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 4a2483bc9..27a3cb9b1 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1797,9 +1797,18 @@ Init12Video(void) DECLSPEC int SDLCALL SDL_VideoInit(const char *driver, Uint32 flags) { - (void) flags; - FIXME("Does this need to call Init12Video?"); - return SDL20_VideoInit(driver); + int retval; + + (void) flags; /* unused. */ + + retval = SDL20_VideoInit(driver); + if (retval != -1) { + retval = Init12Video(); + if (retval == -1) { + SDL20_VideoQuit(); + } + } + return retval; } From 464c725fc2771f80569abd4ea50524b428b84b6b Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 25 Jan 2022 00:06:10 -0500 Subject: [PATCH 209/606] fixme removal: we don't need to force a compatibility GL context here. Presumably we're going to get the system default, which is _probably_ the compatibility profile anyhow, and likely SDL 1.2 would have shook out the same way. We can revisit if bug reports suggest otherwise later, though. Reference Issue #143. --- src/SDL12_compat.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 27a3cb9b1..7ae4435b1 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -5097,7 +5097,6 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12) const char *vsync_env = SDL20_getenv("SDL12COMPAT_SYNC_TO_VBLANK"); SDL_assert(!VideoTexture20); /* either a new window or we destroyed all this */ SDL_assert(!VideoRenderer20); - FIXME("Should we force a compatibility context here?"); FIXME("If we're using logical scaling, we can turn off depth buffer, alpha, etc, since we'll make our own and only need an RGB color buffer for the window."); VideoGLContext20 = SDL20_GL_CreateContext(VideoWindow20); if (!VideoGLContext20) { From 93caa17fbec193f0e023fafd65d4acc8f1226087 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 25 Jan 2022 00:10:28 -0500 Subject: [PATCH 210/606] fixme removal: "wrap surface" Not sure _what_ this meant, but it was likely saying at one point that we need to convert the 1.2 surface to be 2.0 compatible...but we obviously do that now. It might have just been a note to myself to finish implementing this thing, and I forgot to remove the FIXME after? I'm not sure. Reference Issue #143. --- src/SDL12_compat.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 7ae4435b1..db0d8a1af 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -7035,7 +7035,6 @@ SDL_SaveBMP_RW(SDL12_Surface *surface12, SDL12_RWops *rwops12, int freerwops12) { SDL_RWops *rwops20 = RWops12to20(rwops12); const int retval = SDL20_SaveBMP_RW(surface12->surface20, rwops20, freerwops12); - FIXME("wrap surface"); if (!freerwops12) { /* free our wrapper if SDL2 didn't close it. */ SDL20_FreeRW(rwops20); } From 79eb9bf6f16724a273ebcca88c055cb5ffec8918 Mon Sep 17 00:00:00 2001 From: David Gow Date: Fri, 28 Jan 2022 18:14:21 +0800 Subject: [PATCH 211/606] Disable HIGHDPI support by default for unscaled OpenGL apps Many existing OpenGL games don't handle the window-size/drawable-size mismatch that exists on High-DPI systems. We handle this for them when OpenGL Logical Scaling is used, but when it's been disabled (possibly because it's never enabled for windowed-mode), we should not mark our windows as DPI-aware. --- src/SDL12_compat.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index db0d8a1af..22ad56519 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -4927,10 +4927,7 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12) Uint32 appfmt; SDL_bool use_gl_scaling = SDL_FALSE; const char *env; - SDL_bool use_highdpi; - - env = SDL20_getenv("SDL12COMPAT_HIGHDPI"); - use_highdpi = (!env || SDL20_atoi(env)) ? SDL_TRUE : SDL_FALSE; + SDL_bool use_highdpi = SDL_TRUE; FIXME("Should we offer scaling for windowed modes, too?"); if (flags12 & SDL12_OPENGL) { @@ -4947,6 +4944,18 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12) /* for now we default GL scaling to ENABLED. If an app breaks or is linked directly to glBindFramebuffer, they'll need to turn it off with this environment variable */ use_gl_scaling = (!env || SDL20_atoi(env)) ? SDL_TRUE : SDL_FALSE; + + /* default use_highdpi to false for OpenGL windows when not using + OpenGL scaling as legacy OpenGL applications are unlikely to support + high-DPI setups properly. (They often use the window size to determine + the resolute in some or all parts of their code.) Because OpenGL scaling + is never used for windows, it is always false there. */ + use_highdpi = (flags12 & SDL12_FULLSCREEN) ? use_gl_scaling : SDL_FALSE; + } + + env = SDL20_getenv("SDL12COMPAT_HIGHDPI"); + if (env) { + use_highdpi = SDL20_atoi(env) ? SDL_TRUE : SDL_FALSE; } FIXME("currently ignores SDL_WINDOWID, which we could use with SDL_CreateWindowFrom ...?"); From b3328aab36e4c94339f718e315cab5232af02764 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 28 Jan 2022 16:02:15 -0500 Subject: [PATCH 212/606] opengl: _Maybe_ don't destroy an existing GL context during SDL_SetVideoMode. Fixes #156. --- src/SDL12_compat.c | 115 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 89 insertions(+), 26 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 22ad56519..b3a411ec0 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -4850,19 +4850,29 @@ InitializeOpenGLScaling(const int w, const int h) return SDL_FALSE; /* no FBOs, no scaling. */ } + OpenGLFuncs.glBindFramebuffer(GL_FRAMEBUFFER, 0); OpenGLFuncs.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); SDL20_GL_SwapWindow(VideoWindow20); FIXME("This should check if app requested a depth buffer, etc, too."); SDL20_GL_GetAttribute(SDL_GL_ALPHA_SIZE, &alpha_size); - OpenGLFuncs.glGenFramebuffers(1, &OpenGLLogicalScalingFBO); + if (!OpenGLLogicalScalingFBO) { + OpenGLFuncs.glGenFramebuffers(1, &OpenGLLogicalScalingFBO); + } + + if (!OpenGLLogicalScalingColor) { + OpenGLFuncs.glGenRenderbuffers(1, &OpenGLLogicalScalingColor); + } + + if (!OpenGLLogicalScalingDepth) { + OpenGLFuncs.glGenRenderbuffers(1, &OpenGLLogicalScalingDepth); + } + OpenGLFuncs.glBindFramebuffer(GL_FRAMEBUFFER, OpenGLLogicalScalingFBO); - OpenGLFuncs.glGenRenderbuffers(1, &OpenGLLogicalScalingColor); OpenGLFuncs.glBindRenderbuffer(GL_RENDERBUFFER, OpenGLLogicalScalingColor); OpenGLFuncs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, OpenGLLogicalScalingSamples, (alpha_size > 0) ? GL_RGBA8 : GL_RGB8, w, h); OpenGLFuncs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, OpenGLLogicalScalingColor); - OpenGLFuncs.glGenRenderbuffers(1, &OpenGLLogicalScalingDepth); OpenGLFuncs.glBindRenderbuffer(GL_RENDERBUFFER, OpenGLLogicalScalingDepth); OpenGLFuncs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, OpenGLLogicalScalingSamples, GL_DEPTH24_STENCIL8, w, h); OpenGLFuncs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, OpenGLLogicalScalingDepth); @@ -4879,13 +4889,20 @@ InitializeOpenGLScaling(const int w, const int h) } if (OpenGLLogicalScalingSamples) { - OpenGLFuncs.glGenFramebuffers(1, &OpenGLLogicalScalingMultisampleFBO); + if (!OpenGLLogicalScalingMultisampleFBO) { + OpenGLFuncs.glGenFramebuffers(1, &OpenGLLogicalScalingMultisampleFBO); + } + if (!OpenGLLogicalScalingMultisampleColor) { + OpenGLFuncs.glGenRenderbuffers(1, &OpenGLLogicalScalingMultisampleColor); + } + if (!OpenGLLogicalScalingMultisampleDepth) { + OpenGLFuncs.glGenRenderbuffers(1, &OpenGLLogicalScalingMultisampleDepth); + } + OpenGLFuncs.glBindFramebuffer(GL_FRAMEBUFFER, OpenGLLogicalScalingMultisampleFBO); - OpenGLFuncs.glGenRenderbuffers(1, &OpenGLLogicalScalingMultisampleColor); OpenGLFuncs.glBindRenderbuffer(GL_RENDERBUFFER, OpenGLLogicalScalingMultisampleColor); OpenGLFuncs.glRenderbufferStorage(GL_RENDERBUFFER, (alpha_size > 0) ? GL_RGBA8 : GL_RGB8, w, h); OpenGLFuncs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, OpenGLLogicalScalingMultisampleColor); - OpenGLFuncs.glGenRenderbuffers(1, &OpenGLLogicalScalingMultisampleDepth); OpenGLFuncs.glBindRenderbuffer(GL_RENDERBUFFER, OpenGLLogicalScalingMultisampleDepth); OpenGLFuncs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, w, h); OpenGLFuncs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, OpenGLLogicalScalingMultisampleDepth); @@ -5016,21 +5033,62 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12) } else if (VideoSurface12 && (VideoSurface12->surface20->format->format != appfmt)) { EndVidModeCreate(); /* rebuild the window if changing pixel format */ } else if (VideoGLContext20) { - /* SDL 1.2 (infuriatingly!) destroys the GL context on each resize, so we will too */ - SDL20_GL_MakeCurrent(NULL, NULL); - SDL20_GL_DeleteContext(VideoGLContext20); - VideoGLContext20 = NULL; - SDL_zero(OpenGLFuncs); - OpenGLBlitTexture = 0; - OpenGLBlitLockCount = 0; - OpenGLLogicalScalingWidth = 0; - OpenGLLogicalScalingHeight = 0; - OpenGLLogicalScalingFBO = 0; - OpenGLLogicalScalingColor = 0; - OpenGLLogicalScalingDepth = 0; - OpenGLLogicalScalingMultisampleFBO = 0; - OpenGLLogicalScalingMultisampleColor = 0; - OpenGLLogicalScalingMultisampleDepth = 0; + /* SDL 1.2 (infuriatingly!) destroys the GL context on each resize in some cases, on various platforms. Try to match that. */ + #ifdef __WINDOWS__ + /* The windx5 driver _always_ destroyed the GL context, unconditionally, but the default (windib) did not, so match windib. + * windib: keep if: + * - window already exists + * - BitsPerPixel hasn't changed + * - none of the window flags (except SDL_ANYFORMAT) have changed + * - window is already SDL_OPENGL. + * - window is not a fullscreen window. + */ + const SDL_bool destroy_gl_context = ( + ((VideoSurface12->flags & ~SDL12_ANYFORMAT) != (flags12 & ~SDL12_ANYFORMAT)) || + (VideoSurface12->format->BitsPerPixel != bpp) || + ((flags12 & SDL12_OPENGL) != SDL12_OPENGL) || + ((flags12 & SDL12_FULLSCREEN) == SDL12_FULLSCREEN) + ) ? SDL_TRUE : SDL_FALSE; + #elif defined(__APPLE__) + const SDL_bool destroy_gl_context = SDL_TRUE; /* macOS ("quartz" backend) unconditionally destroys the GL context */ + #elif defined(__HAIKU__) + const SDL_bool destroy_gl_context = SDL_FALSE; /* BeOS and Haiku ("bwindow" backend) unconditionally keeps the GL context */ + #elif defined(__LINUX__) || defined(unix) || defined(__unix__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(sun) + /* The x11 backend does in _some_ cases, and since Linux software depends on that, even though Wayland and + * such wasn't a thing at the time, we treat everything that looks a little like Unix this way. + * x11: keep if: + * - window already exists + * - window is already SDL_OPENGL. + * - new flags also want SDL_OPENGL. + * - BitsPerPixel hasn't changed + * - SDL_NOFRAME hasn't changed + */ + const SDL_bool destroy_gl_context = ( + ((VideoSurface12->flags & SDL12_OPENGL) != (flags12 & SDL12_OPENGL)) || + ((flags12 & SDL12_OPENGL) != SDL12_OPENGL) || + (VideoSurface12->format->BitsPerPixel != bpp) || + ((VideoSurface12->flags & SDL12_NOFRAME) != (flags12 & SDL12_NOFRAME)) + ) ? SDL_TRUE : SDL_FALSE; + #else + const SDL_bool destroy_gl_context = SDL_TRUE; /* everywhere else: nuke it from orbit. Oh well. */ + #endif + + if (destroy_gl_context) { + SDL20_GL_MakeCurrent(NULL, NULL); + SDL20_GL_DeleteContext(VideoGLContext20); + VideoGLContext20 = NULL; + SDL_zero(OpenGLFuncs); + OpenGLBlitTexture = 0; + OpenGLBlitLockCount = 0; + OpenGLLogicalScalingWidth = 0; + OpenGLLogicalScalingHeight = 0; + OpenGLLogicalScalingFBO = 0; + OpenGLLogicalScalingColor = 0; + OpenGLLogicalScalingDepth = 0; + OpenGLLogicalScalingMultisampleFBO = 0; + OpenGLLogicalScalingMultisampleColor = 0; + OpenGLLogicalScalingMultisampleDepth = 0; + } } if (flags12 & SDL12_FULLSCREEN) { @@ -5106,16 +5164,19 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12) const char *vsync_env = SDL20_getenv("SDL12COMPAT_SYNC_TO_VBLANK"); SDL_assert(!VideoTexture20); /* either a new window or we destroyed all this */ SDL_assert(!VideoRenderer20); + FIXME("If we're using logical scaling, we can turn off depth buffer, alpha, etc, since we'll make our own and only need an RGB color buffer for the window."); - VideoGLContext20 = SDL20_GL_CreateContext(VideoWindow20); + if (!VideoGLContext20) { - return EndVidModeCreate(); + VideoGLContext20 = SDL20_GL_CreateContext(VideoWindow20); + if (!VideoGLContext20) { + return EndVidModeCreate(); + } + LoadOpenGLFunctions(); } VideoSurface12->flags |= SDL12_OPENGL; - LoadOpenGLFunctions(); - /* Try to set up a logical scaling */ if (use_gl_scaling) { if (!InitializeOpenGLScaling(width, height)) { @@ -5138,7 +5199,9 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12) return EndVidModeCreate(); } - OpenGLFuncs.glGenTextures(1, &OpenGLBlitTexture); + if (!OpenGLBlitTexture) { + OpenGLFuncs.glGenTextures(1, &OpenGLBlitTexture); + } OpenGLFuncs.glBindTexture(GL_TEXTURE_2D, OpenGLBlitTexture); OpenGLFuncs.glTexImage2D(GL_TEXTURE_2D, 0, (pixsize == 4) ? GL_RGBA : GL_RGB, VideoSurface12->w, VideoSurface12->h, 0, glfmt, gltype, NULL); From 4acc507783a545976ce9802e683786f6612df957 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 25 Feb 2022 13:20:37 -0500 Subject: [PATCH 213/606] README: add some notes on building the library --- README.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/README.md b/README.md index 942bc9497..afdfedd06 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,36 @@ new headers are also under the zlib license. Note that sdl12-compat itself does not use these headers, so if you just want the library, you don't need them. +# Building the library: + +These are quick-start instructions; there isn't anything out of the ordinary +here if you're used to using CMake. + +You'll need to use CMake to build sdl12-compat. Download at +[cmake.org](https://cmake.org/) or install from your package manager +(`sudo apt-get install cmake` on Ubuntu, etc). + +Please refer to the [CMake documentation](https://cmake.org/documentation/) +for complete details, as platform and build tool details vary. + +Now just point CMake at sdl12-compat's directory. Here's a command-line +example: + +```bash +cd sdl12-compat +cmake -Bbuild -DCMAKE_BUILD_TYPE=Release . +cmake --build build +``` + +On Windows or macOS, you might prefer to use CMake's GUI, but it's the same +idea: give it the directory where sdl12-compat is located, click "Configure," +choose your favorite compiler, then click "Generate." Then you can build +however you like with Visual Studio, Xcode, etc. + +When the build is complete, you'll have a shared library you can drop in +as a replacement for an existing SDL 1.2 build. This will also build +the original SDL 1.2 test apps, so you can verify the library is working. + # Configuration options: sdl12-compat has a number of configuration options which can be used to work From 4ff7b6373339d74be2d78a2274f183e70767b1d8 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 25 Feb 2022 15:22:29 -0500 Subject: [PATCH 214/606] README: more details on building. --- README.md | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index afdfedd06..a69705945 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,12 @@ You'll need to use CMake to build sdl12-compat. Download at Please refer to the [CMake documentation](https://cmake.org/documentation/) for complete details, as platform and build tool details vary. +You'll need a copy of SDL 2.0.x to build sdl12-compat, because we need the +SDL2 headers. You can build this from source or install from a package +manager. Windows and Mac users can download prebuilt binaries from +[SDL's download page](https://libsdl.org/download-2.0.php); make sure you +get the "development libraries" and not "runtime binaries" there. + Now just point CMake at sdl12-compat's directory. Here's a command-line example: @@ -58,8 +64,16 @@ cmake --build build On Windows or macOS, you might prefer to use CMake's GUI, but it's the same idea: give it the directory where sdl12-compat is located, click "Configure," -choose your favorite compiler, then click "Generate." Then you can build -however you like with Visual Studio, Xcode, etc. +choose your favorite compiler, then click "Generate." Now you have project +files! Click "Open Project" to launch your development environment. Then you +can build however you like with Visual Studio, Xcode, etc. + +If necessary, you might have to fill in the location of the SDL2 headers +when using CMake. sdl12-compat does not need SDL2's library to _build_, +just its headers (although it may complain about the missing library, +you can ignore that). From the command line, add +`-DSDL2_INCLUDE_DIR=/path/to/SDL2/include`, or find this in the CMake +GUI and set it appropriately, click "Configure" again, and then "Generate." When the build is complete, you'll have a shared library you can drop in as a replacement for an existing SDL 1.2 build. This will also build From fede2ffeff0e82d5fca537a91561059fcd803cc3 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Wed, 2 Mar 2022 14:01:23 +0000 Subject: [PATCH 215/606] build: Automatically use legacy GLX library if libOpenGL was not found In older runtime environments like Steam Runtime 1 'scout', we don't necessarily have access to the GLVND dispatch library. Signed-off-by: Simon McVittie --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f4e0779c2..53c819238 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -220,7 +220,7 @@ if(SDL12TESTS) test_program(testdyngl "test/testdyngl.c") test_program(testgl "test/testgl.c") if(OPENGL_FOUND) - if(CMAKE_VERSION VERSION_LESS 3.10) + if(CMAKE_VERSION VERSION_LESS 3.10 OR NOT OPENGL_opengl_LIBRARY) target_link_libraries(testgl ${OPENGL_gl_LIBRARY}) else() target_link_libraries(testgl ${OPENGL_opengl_LIBRARY}) From 406decc52a88f48dc4e534681ced8f72af84544c Mon Sep 17 00:00:00 2001 From: Neal Gompa Date: Wed, 2 Mar 2022 22:32:48 -0500 Subject: [PATCH 216/606] cmake: Rewire and simplify project versioning As we've decided that the emulated SDL version will be the project version for sdl12-compat, unify and simplify the versioning constructs throughout the project so we only have to deal with versioning in one place. --- CMakeLists.txt | 16 ++++++---------- sdl-config.in | 2 +- sdl12_compat.pc.in | 2 +- 3 files changed, 8 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 53c819238..0c31becf8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,11 +4,9 @@ cmake_minimum_required(VERSION 3.0.0) project(sdl12_compat - VERSION 0.0.1 + VERSION 1.2.50 LANGUAGES C) -set(SDL12_COMPAT_VERSION_STR "1.2.50") - option(SDL12TESTS "Enable to build SDL-1.2 test programs" ON) option(SDL12DEVEL "Enable installing SDL-1.2 development headers" ON) option(STATICDEVEL "Enable installing static link library" OFF) @@ -86,7 +84,7 @@ if(APPLE) ) elseif(UNIX AND NOT ANDROID) set_target_properties(SDL PROPERTIES - VERSION "${SDL12_COMPAT_VERSION_STR}" + VERSION "${PROJECT_VERSION}" SOVERSION "0" OUTPUT_NAME "SDL-1.2") elseif(WIN32) @@ -94,18 +92,18 @@ elseif(WIN32) set(CMAKE_SHARED_LIBRARY_PREFIX "") set_target_properties(SDL PROPERTIES COMPILE_DEFINITIONS "DLL_EXPORT") set_target_properties(SDL PROPERTIES - VERSION "${SDL12_COMPAT_VERSION_STR}" + VERSION "${PROJECT_VERSION}" SOVERSION "0" OUTPUT_NAME "SDL") elseif(OS2) set_target_properties(SDL PROPERTIES COMPILE_DEFINITIONS "BUILD_SDL") # for DECLSPEC set_target_properties(SDL PROPERTIES - VERSION "${SDL12_COMPAT_VERSION_STR}" + VERSION "${PROJECT_VERSION}" SOVERSION "0" OUTPUT_NAME "SDL12") else() set_target_properties(SDL PROPERTIES - VERSION "${SDL12_COMPAT_VERSION_STR}" + VERSION "${PROJECT_VERSION}" SOVERSION "0" OUTPUT_NAME "SDL") endif() @@ -239,8 +237,6 @@ install(TARGETS SDL SDLmain ) if(SDL12DEVEL) - set(SDL_VERSION "${SDL12_COMPAT_VERSION_STR}") - install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) if(NOT MSVC) @@ -303,7 +299,7 @@ if(STATICDEVEL AND SDL12DEVEL) set_target_properties(SDL-static PROPERTIES COMPILE_DEFINITIONS "_REENTRANT") target_link_libraries(SDL-static PRIVATE dl) set_target_properties(SDL-static PROPERTIES - VERSION "${SDL12_COMPAT_VERSION_STR}" + VERSION "${PROJECT_VERSION}" OUTPUT_NAME "SDL") install(TARGETS SDL-static diff --git a/sdl-config.in b/sdl-config.in index 528a355ee..ce332b3a6 100755 --- a/sdl-config.in +++ b/sdl-config.in @@ -47,7 +47,7 @@ while test $# -gt 0; do echo $exec_prefix ;; --version) - echo @SDL_VERSION@ + echo @PROJECT_VERSION@ ;; --cflags) echo -I${includedir}/SDL @SDL_CFLAGS@ diff --git a/sdl12_compat.pc.in b/sdl12_compat.pc.in index d5dac574e..30c5028a0 100644 --- a/sdl12_compat.pc.in +++ b/sdl12_compat.pc.in @@ -8,7 +8,7 @@ includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@ Name: sdl12_compat Description: An SDL-1.2 compatibility layer that uses SDL 2.0 behind the scenes. Version: @PROJECT_VERSION@ -Provides: sdl = @SDL_VERSION@ +Provides: sdl = @PROJECT_VERSION@ Libs: -L${libdir} @SDL_RLD_FLAGS@ @SDL_LIBS@ @ENABLE_STATIC_TRUE@Libs.private: -L${libdir} @SDL_LIBS@ @SDL_STATIC_LIBS@ Cflags: -I${includedir}/SDL @SDL_CFLAGS@ From 030111ab691581d2eb0cd44586d69a4398185560 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Thu, 3 Mar 2022 17:56:56 +0300 Subject: [PATCH 217/606] bumped version to 1.2.52 --- CMakeLists.txt | 4 ++-- src/Makefile.darwin | 2 +- src/Makefile.linux | 2 +- src/Makefile.os2 | 2 +- src/Makefile.w32 | 2 +- src/version.rc | 10 +++++----- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0c31becf8..096e18b33 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.0.0) project(sdl12_compat - VERSION 1.2.50 + VERSION 1.2.52 LANGUAGES C) option(SDL12TESTS "Enable to build SDL-1.2 test programs" ON) @@ -22,7 +22,7 @@ if(APPLE) set_source_files_properties(${OSX_SRCS} PROPERTIES LANGUAGE C) # the following matches SDL-1.2 Xcode project file set(DYLIB_COMPAT_VERSION 1.0.0 CACHE STRING "library compatibility version") - set(DYLIB_CURRENT_VERSION 12.50.0 CACHE STRING "library current version") + set(DYLIB_CURRENT_VERSION 12.52.0 CACHE STRING "library current version") include_directories("/opt/X11/include") # hack. if(CMAKE_VERSION VERSION_LESS 3.9) else() diff --git a/src/Makefile.darwin b/src/Makefile.darwin index 77bef81de..5829c16bc 100644 --- a/src/Makefile.darwin +++ b/src/Makefile.darwin @@ -18,7 +18,7 @@ CFLAGS = -mmacosx-version-min=10.6 -fPIC -O3 -Wall LDFLAGS = -mmacosx-version-min=10.6 -dynamiclib -Wl,-undefined,error -Wl,-single_module #LDFLAGS+= -Wl,-headerpad_max_install_names LDFLAGS+= -Wl,-install_name,"/usr/local/lib/$(DYLIB)" -LDFLAGS+= -Wl,-compatibility_version,1.0 -Wl,-current_version,12.50 +LDFLAGS+= -Wl,-compatibility_version,1.0 -Wl,-current_version,12.52 LDLIBS = -Wl,-framework,AppKit # this is needed for x86_64 - cross-gcc might not add it. #LDLIBS += -Wl,-lbundle1.o diff --git a/src/Makefile.linux b/src/Makefile.linux index 9f274bc8a..a5dd4afe8 100644 --- a/src/Makefile.linux +++ b/src/Makefile.linux @@ -16,7 +16,7 @@ LDFLAGS = -shared -Wl,-soname,libSDL-1.2.so.0 LDFLAGS+= -Wl,--no-undefined LDLIBS = -ldl -SHLIB = libSDL-1.2.so.1.2.50 +SHLIB = libSDL-1.2.so.1.2.52 OBJ = SDL12_compat.o diff --git a/src/Makefile.os2 b/src/Makefile.os2 index ca832ad65..5693c8809 100644 --- a/src/Makefile.os2 +++ b/src/Makefile.os2 @@ -5,7 +5,7 @@ !endif DLLNAME = SDL12 -VERSION = 1.2.50 +VERSION = 1.2.52 # change SDL2INC to point to the SDL2 headers SDL2INC = include diff --git a/src/Makefile.w32 b/src/Makefile.w32 index 543e0787f..f400ef0a1 100644 --- a/src/Makefile.w32 +++ b/src/Makefile.w32 @@ -5,7 +5,7 @@ !endif DLLNAME = SDL -VERSION = 1.2.50 +VERSION = 1.2.52 # change SDL2INC to point to the SDL2 headers SDL2INC = include diff --git a/src/version.rc b/src/version.rc index 6292ef1fa..6b4e53bed 100644 --- a/src/version.rc +++ b/src/version.rc @@ -3,8 +3,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,2,50,0 - PRODUCTVERSION 1,2,50,0 + FILEVERSION 1,2,52,0 + PRODUCTVERSION 1,2,52,0 FILEFLAGSMASK 0x3fL FILEFLAGS 0x0L FILEOS 0x40004L @@ -17,12 +17,12 @@ BEGIN BEGIN VALUE "CompanyName", "\0" VALUE "FileDescription", "SDL\0" - VALUE "FileVersion", "1, 2, 50, 0\0" + VALUE "FileVersion", "1, 2, 52, 0\0" VALUE "InternalName", "SDL\0" - VALUE "LegalCopyright", "Copyright © 2021 Sam Lantinga\0" + VALUE "LegalCopyright", "Copyright © 2022 Sam Lantinga\0" VALUE "OriginalFilename", "SDL.dll\0" VALUE "ProductName", "Simple DirectMedia Layer 1.2 wrapper\0" - VALUE "ProductVersion", "1, 2, 50, 0\0" + VALUE "ProductVersion", "1, 2, 52, 0\0" END END BLOCK "VarFileInfo" From cc52691e4f32ad737f50a0a241e902a63fd7d15f Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Thu, 3 Mar 2022 23:00:24 +0300 Subject: [PATCH 218/606] bumped version to 1.2.53 for development. --- CMakeLists.txt | 4 ++-- src/Makefile.darwin | 2 +- src/Makefile.linux | 2 +- src/Makefile.os2 | 2 +- src/Makefile.w32 | 2 +- src/version.rc | 8 ++++---- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 096e18b33..46781ea4f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.0.0) project(sdl12_compat - VERSION 1.2.52 + VERSION 1.2.53 LANGUAGES C) option(SDL12TESTS "Enable to build SDL-1.2 test programs" ON) @@ -22,7 +22,7 @@ if(APPLE) set_source_files_properties(${OSX_SRCS} PROPERTIES LANGUAGE C) # the following matches SDL-1.2 Xcode project file set(DYLIB_COMPAT_VERSION 1.0.0 CACHE STRING "library compatibility version") - set(DYLIB_CURRENT_VERSION 12.52.0 CACHE STRING "library current version") + set(DYLIB_CURRENT_VERSION 12.53.0 CACHE STRING "library current version") include_directories("/opt/X11/include") # hack. if(CMAKE_VERSION VERSION_LESS 3.9) else() diff --git a/src/Makefile.darwin b/src/Makefile.darwin index 5829c16bc..7d4e81992 100644 --- a/src/Makefile.darwin +++ b/src/Makefile.darwin @@ -18,7 +18,7 @@ CFLAGS = -mmacosx-version-min=10.6 -fPIC -O3 -Wall LDFLAGS = -mmacosx-version-min=10.6 -dynamiclib -Wl,-undefined,error -Wl,-single_module #LDFLAGS+= -Wl,-headerpad_max_install_names LDFLAGS+= -Wl,-install_name,"/usr/local/lib/$(DYLIB)" -LDFLAGS+= -Wl,-compatibility_version,1.0 -Wl,-current_version,12.52 +LDFLAGS+= -Wl,-compatibility_version,1.0 -Wl,-current_version,12.53 LDLIBS = -Wl,-framework,AppKit # this is needed for x86_64 - cross-gcc might not add it. #LDLIBS += -Wl,-lbundle1.o diff --git a/src/Makefile.linux b/src/Makefile.linux index a5dd4afe8..def560386 100644 --- a/src/Makefile.linux +++ b/src/Makefile.linux @@ -16,7 +16,7 @@ LDFLAGS = -shared -Wl,-soname,libSDL-1.2.so.0 LDFLAGS+= -Wl,--no-undefined LDLIBS = -ldl -SHLIB = libSDL-1.2.so.1.2.52 +SHLIB = libSDL-1.2.so.1.2.53 OBJ = SDL12_compat.o diff --git a/src/Makefile.os2 b/src/Makefile.os2 index 5693c8809..2d71d50d2 100644 --- a/src/Makefile.os2 +++ b/src/Makefile.os2 @@ -5,7 +5,7 @@ !endif DLLNAME = SDL12 -VERSION = 1.2.52 +VERSION = 1.2.53 # change SDL2INC to point to the SDL2 headers SDL2INC = include diff --git a/src/Makefile.w32 b/src/Makefile.w32 index f400ef0a1..00270ee04 100644 --- a/src/Makefile.w32 +++ b/src/Makefile.w32 @@ -5,7 +5,7 @@ !endif DLLNAME = SDL -VERSION = 1.2.52 +VERSION = 1.2.53 # change SDL2INC to point to the SDL2 headers SDL2INC = include diff --git a/src/version.rc b/src/version.rc index 6b4e53bed..9bd5627f5 100644 --- a/src/version.rc +++ b/src/version.rc @@ -3,8 +3,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,2,52,0 - PRODUCTVERSION 1,2,52,0 + FILEVERSION 1,2,53,0 + PRODUCTVERSION 1,2,53,0 FILEFLAGSMASK 0x3fL FILEFLAGS 0x0L FILEOS 0x40004L @@ -17,12 +17,12 @@ BEGIN BEGIN VALUE "CompanyName", "\0" VALUE "FileDescription", "SDL\0" - VALUE "FileVersion", "1, 2, 52, 0\0" + VALUE "FileVersion", "1, 2, 53, 0\0" VALUE "InternalName", "SDL\0" VALUE "LegalCopyright", "Copyright © 2022 Sam Lantinga\0" VALUE "OriginalFilename", "SDL.dll\0" VALUE "ProductName", "Simple DirectMedia Layer 1.2 wrapper\0" - VALUE "ProductVersion", "1, 2, 52, 0\0" + VALUE "ProductVersion", "1, 2, 53, 0\0" END END BLOCK "VarFileInfo" From f4980108b0fbe59e04aaba6b18be760a607ab923 Mon Sep 17 00:00:00 2001 From: David Gow Date: Mon, 7 Mar 2022 16:01:50 +0800 Subject: [PATCH 219/606] Set 'pixels' in SDL_CreateYUVOverlay() (Fix #164) Some applications, such as mplayer with -vo sdl will access the 'pixels' member of an SDL_Overlay immediately after creating it, without ever locking it. This works on (at least some backends for) SDL 1.2, but crashed on sdl12-compat, as pixels remained unset until SDL_LockYUVOverlay() is called. Set pixels in SDL_CreateYUVOverlay(), as well as hwdata->dirty, which makes it possible to have a working YUV overlay without ever locking/unlocking it. This is required for mplayer's sdl vo backend to function. Fixes issue #164 --- src/SDL12_compat.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index b3a411ec0..b5a851bca 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -6337,6 +6337,10 @@ SDL_CreateYUVOverlay(int w, int h, Uint32 format12, SDL12_Surface *display12) retval->hw_overlay = 1; retval->pitches = hwdata->pitches; + /* Some programs (e.g. mplayer) access pixels without locking. */ + retval->pixels = hwdata->pixels; + hwdata->dirty = SDL_TRUE; + return retval; } From 32bcfa763d90cd2391493a396f21b98716b52bda Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 8 Mar 2022 15:19:41 -0500 Subject: [PATCH 220/606] SDL_GetWMInfo: work like 1.2 when SDL_SetVideoMode() hasn't been called yet. Fixes #163. --- src/SDL12_compat.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index b5a851bca..ea99f2cf8 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -6218,6 +6218,9 @@ DECLSPEC int SDLCALL SDL_GetWMInfo(SDL12_SysWMinfo *info12) { SDL_SysWMinfo info20; + SDL_bool temp_window = SDL_FALSE; + SDL_Window *win20 = VideoWindow20; + int rc; if (info12->version.major > 1) { SDL20_SetError("Requested version is unsupported"); @@ -6227,15 +6230,30 @@ SDL_GetWMInfo(SDL12_SysWMinfo *info12) return 0; /* some programs only test against 0, not -1 */ } + if (win20 == NULL) { + /* It was legal to call SDL_GetWMInfo without SDL_SetVideoMode() on X11 and Windows (and others...?) in 1.2. */ + win20 = SDL20_CreateWindow("SDL_GetWMInfo support window", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 128, 128, SDL_WINDOW_HIDDEN); + if (!win20) { + return 0; + } + temp_window = SDL_TRUE; + } + SDL_zero(info20); SDL_VERSION(&info20.version); - if (!SDL20_GetWindowWMInfo(VideoWindow20, &info20)) { + rc = SDL20_GetWindowWMInfo(win20, &info20); + + if (temp_window) { + SDL20_DestroyWindow(win20); + } + + if (!rc) { return 0; /* some programs only test against 0, not -1 */ } #if defined(SDL_VIDEO_DRIVER_WINDOWS) SDL_assert(info20.subsystem == SDL_SYSWM_WINDOWS); - info12->window = info20.info.win.window; + info12->window = temp_window ? 0 : info20.info.win.window; if (SDL_VERSIONNUM(info12->version.major, info12->version.minor, info12->version.patch) >= SDL_VERSIONNUM(1, 2, 5)) { info12->hglrc = (HGLRC) VideoGLContext20; } @@ -6243,7 +6261,7 @@ SDL_GetWMInfo(SDL12_SysWMinfo *info12) SDL_assert(info20.subsystem == SDL_SYSWM_X11); info12->subsystem = SDL12_SYSWM_X11; info12->info.x11.display = info20.info.x11.display; - info12->info.x11.window = info20.info.x11.window; + info12->info.x11.window = temp_window ? 0 : info20.info.x11.window; if (SDL_VERSIONNUM(info12->version.major, info12->version.minor, info12->version.patch) >= SDL_VERSIONNUM(1, 0, 2)) { info12->info.x11.fswindow = 0; /* these don't exist in SDL2. */ info12->info.x11.wmwindow = 0; From 2bd433920d568b0231aec80ce07e7b0fe916ec1e Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Tue, 8 Mar 2022 23:51:10 +0300 Subject: [PATCH 221/606] minor whitespace tidy-up. --- src/SDL12_compat.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index ea99f2cf8..733ece64d 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -4879,7 +4879,7 @@ InitializeOpenGLScaling(const int w, const int h) OpenGLFuncs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, OpenGLLogicalScalingDepth); OpenGLFuncs.glBindRenderbuffer(GL_RENDERBUFFER, 0); - if ( (OpenGLFuncs.glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) || OpenGLFuncs.glGetError() ) { + if ((OpenGLFuncs.glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) || OpenGLFuncs.glGetError()) { OpenGLFuncs.glBindFramebuffer(GL_FRAMEBUFFER, 0); OpenGLFuncs.glDeleteRenderbuffers(1, &OpenGLLogicalScalingColor); OpenGLFuncs.glDeleteRenderbuffers(1, &OpenGLLogicalScalingDepth); @@ -4909,7 +4909,7 @@ InitializeOpenGLScaling(const int w, const int h) OpenGLFuncs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, OpenGLLogicalScalingMultisampleDepth); OpenGLFuncs.glBindRenderbuffer(GL_RENDERBUFFER, 0); - if ( (OpenGLFuncs.glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) || OpenGLFuncs.glGetError() ) { + if ((OpenGLFuncs.glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) || OpenGLFuncs.glGetError()) { OpenGLFuncs.glBindFramebuffer(GL_FRAMEBUFFER, 0); OpenGLFuncs.glDeleteRenderbuffers(1, &OpenGLLogicalScalingMultisampleColor); OpenGLFuncs.glDeleteRenderbuffers(1, &OpenGLLogicalScalingMultisampleDepth); @@ -5028,7 +5028,7 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12) FIXME("don't do anything if the window's dimensions, etc haven't changed."); FIXME("we need to preserve VideoSurface12 (but not its pixels), I think..."); - if (VideoSurface12 && ((VideoSurface12->flags & SDL12_OPENGL) != (flags12 & SDL12_OPENGL)) ) { + if (VideoSurface12 && ((VideoSurface12->flags & SDL12_OPENGL) != (flags12 & SDL12_OPENGL))) { EndVidModeCreate(); /* rebuild the window if moving to/from a GL context */ } else if (VideoSurface12 && (VideoSurface12->surface20->format->format != appfmt)) { EndVidModeCreate(); /* rebuild the window if changing pixel format */ @@ -6557,11 +6557,11 @@ SDL_GL_GetAttribute(SDL12_GLattr attr, int* value) else if (attr == SDL12_GL_MULTISAMPLESAMPLES) { *value = OpenGLLogicalScalingSamples; return 0; - } + } else if (attr == SDL12_GL_MULTISAMPLEBUFFERS) { *value = (OpenGLLogicalScalingSamples) ? 1 : 0; return 0; - } + } /* SDL2 has a bug where FBO 0 must be bound or SDL20_GL_GetAttribute gives incorrect information. See https://github.com/libsdl-org/sdl12-compat/issues/150 */ @@ -7939,8 +7939,8 @@ OpenSDL2AudioDevice(SDL_AudioSpec *want) if ( (want->freq > have->freq) || (want->channels > have->channels) || (want->samples > have->samples) || - ( (SDL_AUDIO_ISFLOAT(want->format)) && (!SDL_AUDIO_ISFLOAT(have->format)) ) || - ( SDL_AUDIO_BITSIZE(want->format) > SDL_AUDIO_BITSIZE(have->format) ) ) { + (SDL_AUDIO_ISFLOAT(want->format) && !SDL_AUDIO_ISFLOAT(have->format)) || + (SDL_AUDIO_BITSIZE(want->format) > SDL_AUDIO_BITSIZE(have->format)) ) { SDL20_CloseAudio(); } else { SDL20_LockAudio(); /* Device is already at acceptable parameters, just pause it for further setup by caller. */ From 06d554b9d1f5fd8d73072331f33ed8ff0bad66c2 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Mon, 14 Mar 2022 10:20:02 +0300 Subject: [PATCH 222/606] SDL_endian.h: use endian predefs from newer gcc and clang versions. --- include/SDL/SDL_endian.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/include/SDL/SDL_endian.h b/include/SDL/SDL_endian.h index 872f31082..fb27d371e 100644 --- a/include/SDL/SDL_endian.h +++ b/include/SDL/SDL_endian.h @@ -47,6 +47,15 @@ real SDL-1.2 available to you. */ #elif defined(__FreeBSD__) || defined(__NetBSD__) #include #define SDL_BYTEORDER BYTE_ORDER +/* predefs from newer gcc and clang versions: */ +#elif defined(__ORDER_LITTLE_ENDIAN__) && defined(__ORDER_BIG_ENDIAN__) && defined(__BYTE_ORDER__) +#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) +#define SDL_BYTEORDER SDL_LIL_ENDIAN +#elif (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) +#define SDL_BYTEORDER SDL_BIG_ENDIAN +#else +#error Unsupported endianness +#endif /**/ #else #if defined(__hppa__) || \ defined(__m68k__) || defined(mc68000) || defined(_M_M68K) || \ From 201670ec0a3324fd959acf6dadda51bd8041b3f8 Mon Sep 17 00:00:00 2001 From: David Gow Date: Wed, 9 Mar 2022 21:29:50 +0800 Subject: [PATCH 223/606] Handle SDL12_Surface::refcount in SDL_FreeSurface SDL_Surface has a refcount field, and surfaces shouldn't be destroyed until it's zero. Confusingly, in sdl12-compat, there are two refcount fields: one for the SDL 1.2 surface, and one for the SDL 2.0 surface used to implement it. There are two ways this could be implemented: 1) Keep the SDL12_Surface and SDL20_Surface refcounts synchronised across every call into SDL2. 2) Completely separate the refcounts. This implements option 2: the SDL12_Surface's refcount is set to 1 when created, not to be equal to the SDL2 surface's refcount. We then decrement this and free it as required. This is safe for two reasons: - As long as the 1.2 surface's refcount is > 0, there must be at least one reference to the 2.0 surface. - It turns out nothing in SDL 2 is actually using the SDL 2 surface refcount. This makes "frogatto"[1] not crash on startup with a double-free of SDL_Surfaces, as it makes heavy use of the SDL 1.2 refcount field[2]. [1]: https://frogatto.com/download/ [2]: https://github.com/frogatto/frogatto/blob/1.2_stable/src/surface.hpp --- src/SDL12_compat.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 733ece64d..36778565b 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -4325,6 +4325,9 @@ DECLSPEC void SDLCALL SDL_FreeSurface(SDL12_Surface *surface12) { if (surface12 && (surface12 != VideoSurface12)) { + surface12->refcount--; + if (surface12->refcount) + return; SDL20_FreeSurface(surface12->surface20); if (surface12->format) { SDL20_free(surface12->format->palette); From c92f6807e05955fbe35098ff12f687dc6ec12aca Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 14 Mar 2022 13:24:05 -0400 Subject: [PATCH 224/606] Convert "borderless fullscreen windowed mode" into FULLSCREEN_DESKTOP. Corrects window creation for Awesomenauts (which still doesn't render with sdl12-compat; this is a separate problem from that). Reference issue #168. --- README.md | 9 +++++++++ src/SDL12_compat.c | 11 +++++++++++ test/testsprite.c | 3 +++ 3 files changed, 23 insertions(+) diff --git a/README.md b/README.md index a69705945..1702b34dc 100644 --- a/README.md +++ b/README.md @@ -111,6 +111,15 @@ The available options are: option is enabled by default, but not all applications are compatible with it: try changing this if you can only see a black screen. +- SDL12COMPAT_FIX_BORDERLESS_FS_WIN: + Enables turning borderless windows at the desktop resolution into actual + fullscreen windows (so they'll go into a separate space on macOS and + properly hide dock windows on other desktop environments, etc). + If disabled, applications may not get the full display to theirselves as + they expect. This option is enabled by default, but this option is here + so it can be manually disabled, in case this causes some negative result + we haven't anticipated. + - SDL12COMPAT_SCALE_METHOD: Choose the scaling method used when applications render at a non-native resolution. The options are `nearest`, for nearest-neighbour sampling diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 36778565b..f79c90241 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -4948,6 +4948,7 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12) SDL_bool use_gl_scaling = SDL_FALSE; const char *env; SDL_bool use_highdpi = SDL_TRUE; + SDL_bool fix_bordless_fs_win = SDL_TRUE; FIXME("Should we offer scaling for windowed modes, too?"); if (flags12 & SDL12_OPENGL) { @@ -4978,6 +4979,11 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12) use_highdpi = SDL20_atoi(env) ? SDL_TRUE : SDL_FALSE; } + env = SDL20_getenv("SDL12COMPAT_FIX_BORDERLESS_FS_WIN"); + if (env) { + fix_bordless_fs_win = SDL20_atoi(env) ? SDL_TRUE : SDL_FALSE; + } + FIXME("currently ignores SDL_WINDOWID, which we could use with SDL_CreateWindowFrom ...?"); flags12 &= ~SDL12_HWACCEL; /* just in case - https://github.com/libsdl-org/SDL-1.2/issues/817 */ @@ -5104,6 +5110,11 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12) } else { fullscreen_flags20 |= SDL_WINDOW_FULLSCREEN; } + } else if (fix_bordless_fs_win && (flags12 & SDL12_NOFRAME) && (width == dmode.w) && (height == dmode.h)) { + /* app appears to be trying to do a "borderless fullscreen windowed" mode, so just bump + it to FULLSCREEN_DESKTOP so it cooperates with various display managers + (into a fullscreen space on macOS, hide the Dock on Gnome, etc). */ + fullscreen_flags20 |= SDL_WINDOW_FULLSCREEN_DESKTOP; } if (!VideoWindow20) { /* create it */ diff --git a/test/testsprite.c b/test/testsprite.c index f83de9a14..0e2fd17cd 100644 --- a/test/testsprite.c +++ b/test/testsprite.c @@ -202,6 +202,9 @@ int main(int argc, char *argv[]) if ( strcmp(argv[argc], "-fullscreen") == 0 ) { videoflags ^= SDL_FULLSCREEN; } else + if ( strcmp(argv[argc], "-noframe") == 0 ) { + videoflags ^= SDL_NOFRAME; + } else if ( isdigit(argv[argc][0]) ) { numsprites = atoi(argv[argc]); } else { From 2c813c7e7bb44873f28ae1b5737a74fa209c6cd2 Mon Sep 17 00:00:00 2001 From: David Gow Date: Wed, 16 Mar 2022 19:15:07 +0800 Subject: [PATCH 225/606] Update SDL12_COMPAT_VERSION to 53 for 1.2.53 (Whoops, we forgot to update this for 1.2.52. :/) This is used by SDL_Linked_Version(). Maybe it'd make sense to inject this from the build system, which should already know what the version is. In the meantime, however, report 1.2.53. --- src/SDL12_compat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index f79c90241..dea22ce37 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -28,7 +28,7 @@ * should be way ahead of what SDL-1.2 Classic would report, so apps can * decide if they're running under the compat layer, if they really care. */ -#define SDL12_COMPAT_VERSION 50 +#define SDL12_COMPAT_VERSION 53 #include #include From f0cc75faea16140e8a9c8511125e50113cba947c Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Thu, 17 Mar 2022 05:41:20 +0300 Subject: [PATCH 226/606] fixed a typo in Makefile.w32 --- src/Makefile.w32 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile.w32 b/src/Makefile.w32 index 00270ee04..0585d17e5 100644 --- a/src/Makefile.w32 +++ b/src/Makefile.w32 @@ -75,7 +75,7 @@ clean: .SYMBOLIC @echo * Clean: $(LIBNAME) $(VERSION) @if exist *.obj rm *.obj @if exist *.res rm *.res - @if exist *.map rm *.lbc + @if exist *.lbc rm *.lbc @if exist *.map rm *.map @if exist $(LNKFILE) rm $(LNKFILE) From 7e7850a882216eb79e8d2ef3b7c25ab1c15632f0 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 17 Mar 2022 09:53:08 -0700 Subject: [PATCH 227/606] Renamed testhread to testthread Fixes https://github.com/libsdl-org/sdl12-compat/issues/172 --- CMakeLists.txt | 2 +- test/README | 2 +- test/{testhread.c => testthread.c} | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename test/{testhread.c => testthread.c} (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 46781ea4f..0e96b6b07 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -196,7 +196,7 @@ if(SDL12TESTS) test_program(testerror "test/testerror.c") test_program(testfile "test/testfile.c") test_program(testgamma "test/testgamma.c") - test_program(testthread "test/testhread.c") + test_program(testthread "test/testthread.c") test_program(testiconv "test/testiconv.c") test_program(testjoystick "test/testjoystick.c") test_program(testkeys "test/testkeys.c") diff --git a/test/README b/test/README index 9cf5659c7..e158b4e42 100644 --- a/test/README +++ b/test/README @@ -14,7 +14,6 @@ These are test programs for the SDL library: testfile Tests RWops layer testgamma Tests video device gamma ramp testgl A very simple example of using OpenGL with SDL - testhread Hacked up test of multi-threading testiconv Tests international string conversion testjoystick List joysticks and watch joystick events testkeys List the available keyboard keys @@ -26,6 +25,7 @@ These are test programs for the SDL library: testplatform Tests types, endianness and cpu capabilities testsem Tests SDL's semaphore implementation testsprite Example of fast sprite movement on the screen + testthread Hacked up test of multi-threading testtimer Test the timer facilities testver Check the version and dynamic loading and endianness testvidinfo Show the pixel format of the display and perfom the benchmark diff --git a/test/testhread.c b/test/testthread.c similarity index 100% rename from test/testhread.c rename to test/testthread.c From 64aadc249012c27406be839128536a83b1ba4d15 Mon Sep 17 00:00:00 2001 From: David Gow Date: Wed, 16 Mar 2022 21:39:30 +0800 Subject: [PATCH 228/606] Implement a "quirks" system for application-specific workarounds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There are enough application-specific compatibility workarounds that it may be worth keeping a database of them and automatically applying them. This implementation adds a "quirks table": an array listing the executable name and a series of string→string maps which match the "hints" we've previously used manually. All of those hints now go via an SDL12Compat_GetHint() function, which will check the environment variable first, then look up a quirk based on the executable name, then fallback to the default. Apart from the compatibility table, this roughly reflects the SDL2 Hints system (albeit simplified somewhat). This includes a new SDL12Compat_GetHintBoolean() function which does most of the nasty calls to atoi() and ternary-operator use which previously happened for every environment variable check. It also adds a few quirks by default (for Awesomenauts, Braid, and DOSBox), and will print out any quirks associated with the application on startup if SDL12COMPAT_DEBUG_LOGGING is enabled. --- src/SDL12_compat.c | 170 ++++++++++++++++++++++++++++++------ src/SDL20_include_wrapper.h | 1 + 2 files changed, 143 insertions(+), 28 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index dea22ce37..ee6ed6a47 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -59,6 +59,10 @@ #define SDL_BlitSurface SDL_UpperBlit +#ifdef __LINUX__ +#include /* for readlink() */ +#endif + #ifdef __cplusplus extern "C" { #endif @@ -1122,6 +1126,123 @@ UnloadSDL20(void) CloseSDL20Library(); } +typedef struct QuirkEntryType +{ + const char *exe_name; + const char *hint_name; + const char *hint_value; +} QuirkEntryType; + +static QuirkEntryType quirks[] = { +#if defined(__unix__) + /* Awesomenauts uses Cg, and does weird things with the GL context. */ + {"Awesomenauts.bin.x86", "SDL12COMPAT_OPENGL_SCALING", "0"}, + {"Awesomenauts.bin.x86", "SDL_VIDEODRIVER", "x11"}, + + /* Braid uses Cg, which uses glXGetProcAddress(). */ + {"braid", "SDL_VIDEODRIVER", "x11"}, + {"braid", "SDL12COMPAT_OPENGL_SCALING", "0"}, + + /* GOG's DOSBox builds have architecture-specific filenames. */ + {"dosbox", "SDL12COMPAT_USE_KEYBOARD_LAYOUT", "0"}, + {"dosbox_i686", "SDL12COMPAT_USE_KEYBOARD_LAYOUT", "0"}, + {"dosbox_x86_64", "SDL12COMPAT_USE_KEYBOARD_LAYOUT", "0"} +#else + /* TODO: Add any quirks needed for this system. */ + + /* A dummy entry to keep compilers happy. */ + {"", "", NULL} +#endif +}; + +static const char * +SDL12Compat_GetExeName(void) +{ + static const char *exename = NULL; + if (exename == NULL) { + static char path_buf[260]; + static char *base_path; +#ifdef _WIN32 + GetModuleFileName(NULL, path_buf, 260); +#elif defined(__linux__) + readlink("/proc/self/exe", path_buf, 260); +#elif defined(__OS2__) + PTIB tib; + PPIB pib; + DosGetInfoBlocks(&tib, &pib); + DosQueryModuleName(pib->pib_hmte, 260, path_buf); +#else + path_buf[0] = '\0'; +#endif + base_path = SDL20_strrchr(path_buf, *DIRSEP); + if (base_path) { + /* We have a '\\' component. */ + exename = base_path + 1; + } else { + /* No slashes, return the whole module filanem. */ + exename = path_buf; + } + } + return exename; +} + +static const char * +SDL12Compat_GetHint(const char *name) +{ + const char *value; + const char *exe_name; + int i; + + /* First, check if there's an environment variable override. */ + value = SDL20_getenv(name); + if (value) { + return value; + } + + /* Else, look up the quirks table. */ + exe_name = SDL12Compat_GetExeName(); + for (i = 0; i < SDL_arraysize(quirks); i++) { + if (!SDL20_strcmp(exe_name, quirks[i].exe_name)) { + if (!SDL20_strcmp(name, quirks[i].hint_name)) { + return quirks[i].hint_value; + } + } + } + + /* No value was found, NULL by default. */ + return NULL; +} + +static SDL_bool +SDL12Compat_GetHintBoolean(const char *name, SDL_bool default_value) +{ + const char *val = SDL12Compat_GetHint(name); + + if (!val) { + return default_value; + } + + return (SDL20_atoi(val) != 0) ? SDL_TRUE : SDL_FALSE; +} + +static void +SDL12Compat_PrintQuirks(void) +{ + int i; + const char *exe_name = SDL12Compat_GetExeName(); + + for (i = 0; i < SDL_arraysize(quirks); i++) { + if (!SDL20_strcmp(exe_name, quirks[i].exe_name)) { + if (!SDL20_getenv(quirks[i].hint_name)) { + SDL20_Log("Applying compatibility quirk %s=\"%s\" for \"%s\"", quirks[i].hint_name, quirks[i].hint_value, exe_name); + } else { + SDL20_Log("Not applying compatibility quirk %s=\"%s\" for \"%s\" due to environment variable override (\"%s\")\n", + quirks[i].hint_name, quirks[i].hint_value, exe_name, SDL20_getenv(quirks[i].hint_name)); + } + } + } +} + static int LoadSDL20(void) { @@ -1141,8 +1262,7 @@ LoadSDL20(void) if (!okay) { sprintf_fn(loaderror, "SDL2 %d.%d.%d library is too old.", v.major, v.minor, v.patch); } else { - const char *envr = SDL20_getenv("SDL12COMPAT_DEBUG_LOGGING"); - const SDL_bool debug_logging = (!envr || (SDL20_atoi(envr) == 0)) ? SDL_FALSE : SDL_TRUE; + const SDL_bool debug_logging = SDL12Compat_GetHintBoolean("SDL12COMPAT_DEBUG_LOGGING", SDL_FALSE); #if ENABLE_FIXMES == 1 PrintFixmes = debug_logging; #endif @@ -1152,6 +1272,8 @@ LoadSDL20(void) #else SDL20_Log("sdl12-compat, talking to SDL2 %d.%d.%d", v.major, v.minor, v.patch); #endif + /* Print a list of any enabled quirks. */ + SDL12Compat_PrintQuirks(); } } } @@ -1259,7 +1381,6 @@ SDL_SetModuleHandle(void *handle) } #endif - DECLSPEC const SDL_version * SDLCALL SDL_Linked_Version(void) { @@ -1630,8 +1751,7 @@ Init12VidModes(void) int i, j; SDL12_Rect prev_mode = { 0, 0, 0, 0 }, current_mode = { 0, 0, 0, 0 }; /* We only want to enable fake modes if OpenGL Logical Scaling is enabled. */ - const char *env = SDL20_getenv("SDL12COMPAT_OPENGL_SCALING"); - SDL_bool use_fake_modes = (!env || SDL20_atoi(env)) ? SDL_TRUE : SDL_FALSE; + SDL_bool use_fake_modes = SDL12Compat_GetHintBoolean("SDL12COMPAT_OPENGL_SCALING", SDL_TRUE); if (VideoModesCount > 0) { return 0; /* already did this. */ @@ -1733,14 +1853,11 @@ static int Init12Video(void) { const char *driver = SDL20_GetCurrentVideoDriver(); - const char *layout_env = SDL20_getenv("SDL12COMPAT_USE_KEYBOARD_LAYOUT"); SDL_DisplayMode mode; int i; /* Only override this if the env var is set, as the default is platform-specific. */ - if (layout_env) { - TranslateKeyboardLayout = SDL20_atoi(layout_env) ? SDL_TRUE : SDL_FALSE; - } + TranslateKeyboardLayout = SDL12Compat_GetHintBoolean("SDL12COMPAT_USE_KEYBOARD_LAYOUT", TranslateKeyboardLayout); IsDummyVideo = ((driver != NULL) && (SDL20_strcmp(driver, "dummy") == 0)) ? SDL_TRUE : SDL_FALSE; @@ -1820,6 +1937,7 @@ DECLSPEC int SDLCALL SDL_InitSubSystem(Uint32 sdl12flags) { Uint32 sdl20flags = 0; + const char *forcevideodrv; int rc; #ifdef __WINDOWS__ @@ -1838,6 +1956,12 @@ SDL_InitSubSystem(Uint32 sdl12flags) sdl12_compat_macos_init(); #endif + /* Some applications need to force a specific videodriver. */ + forcevideodrv = SDL12Compat_GetHint("SDL_VIDEODRIVER"); + if (forcevideodrv) { + SDL20_setenv("SDL_VIDEODRIVER", forcevideodrv, 1); + } + FIXME("support SDL_INIT_EVENTTHREAD where it makes sense?"); #define SETFLAG(flag) if (sdl12flags & SDL12_INIT_##flag) sdl20flags |= SDL_INIT_##flag SETFLAG(TIMER); @@ -4842,12 +4966,10 @@ glCopyTexSubImage3D_shim_for_scaling(GLenum target, GLint level, GLint xoffset, static SDL_bool InitializeOpenGLScaling(const int w, const int h) { - const char *env; int alpha_size = 0; /* Support the MOUSE_RELATIVE_SCALING hint from SDL 2.0 for OpenGL scaling. */ - env = SDL20_getenv("SDL_MOUSE_RELATIVE_SCALING"); - UseMouseRelativeScaling = (!env || SDL20_atoi(env)) ? SDL_TRUE : SDL_FALSE; + UseMouseRelativeScaling = SDL12Compat_GetHintBoolean("SDL_MOUSE_RELATIVE_SCALING", SDL_TRUE); if (!OpenGLFuncs.SUPPORTS_GL_ARB_framebuffer_object) { return SDL_FALSE; /* no FBOs, no scaling. */ @@ -4946,7 +5068,6 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12) Uint32 fullscreen_flags20 = 0; Uint32 appfmt; SDL_bool use_gl_scaling = SDL_FALSE; - const char *env; SDL_bool use_highdpi = SDL_TRUE; SDL_bool fix_bordless_fs_win = SDL_TRUE; @@ -4960,11 +5081,10 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12) maybe need to export the symbol from here too, for those that link against OpenGL directly. UT2004 is known to use FBOs with SDL 1.2, and I assume idTech 4 games (Doom 3, Quake 4, Prey) do as well. */ - env = SDL20_getenv("SDL12COMPAT_OPENGL_SCALING"); /* for now we default GL scaling to ENABLED. If an app breaks or is linked directly to glBindFramebuffer, they'll need to turn it off with this environment variable */ - use_gl_scaling = (!env || SDL20_atoi(env)) ? SDL_TRUE : SDL_FALSE; + use_gl_scaling = SDL12Compat_GetHintBoolean("SDL12COMPAT_OPENGL_SCALING", SDL_TRUE); /* default use_highdpi to false for OpenGL windows when not using OpenGL scaling as legacy OpenGL applications are unlikely to support @@ -4974,15 +5094,9 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12) use_highdpi = (flags12 & SDL12_FULLSCREEN) ? use_gl_scaling : SDL_FALSE; } - env = SDL20_getenv("SDL12COMPAT_HIGHDPI"); - if (env) { - use_highdpi = SDL20_atoi(env) ? SDL_TRUE : SDL_FALSE; - } + use_highdpi = SDL12Compat_GetHintBoolean("SDL12COMPAT_HIGHDPI", use_highdpi); - env = SDL20_getenv("SDL12COMPAT_FIX_BORDERLESS_FS_WIN"); - if (env) { - fix_bordless_fs_win = SDL20_atoi(env) ? SDL_TRUE : SDL_FALSE; - } + fix_bordless_fs_win = SDL12Compat_GetHintBoolean("SDL12COMPAT_FIX_BORDERLESS_FS_WIN", fix_bordless_fs_win); FIXME("currently ignores SDL_WINDOWID, which we could use with SDL_CreateWindowFrom ...?"); @@ -5175,7 +5289,7 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12) } if (flags12 & SDL12_OPENGL) { - const char *vsync_env = SDL20_getenv("SDL12COMPAT_SYNC_TO_VBLANK"); + const char *vsync_env = SDL12Compat_GetHint("SDL12COMPAT_SYNC_TO_VBLANK"); SDL_assert(!VideoTexture20); /* either a new window or we destroyed all this */ SDL_assert(!VideoRenderer20); @@ -5237,9 +5351,9 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12) } else { /* always use a renderer for non-OpenGL windows. */ - const char *vsync_env = SDL20_getenv("SDL12COMPAT_SYNC_TO_VBLANK"); + const char *vsync_env = SDL12Compat_GetHint("SDL12COMPAT_SYNC_TO_VBLANK"); const char *old_scale_quality = SDL20_GetHint(SDL_HINT_RENDER_SCALE_QUALITY); - const char *scale_method_env = SDL20_getenv("SDL12COMPAT_SCALE_METHOD"); + const char *scale_method_env = SDL12Compat_GetHint("SDL12COMPAT_SCALE_METHOD"); const SDL_bool want_vsync = (vsync_env && SDL20_atoi(vsync_env)) ? SDL_TRUE : SDL_FALSE; const SDL_bool want_nearest = (scale_method_env && !SDL20_strcmp(scale_method_env, "nearest"))? SDL_TRUE : SDL_FALSE; SDL_RendererInfo rinfo; @@ -6598,7 +6712,7 @@ SDL_GL_SwapBuffers(void) if (VideoWindow20) { if (OpenGLLogicalScalingFBO != 0) { const GLboolean has_scissor = OpenGLFuncs.glIsEnabled(GL_SCISSOR_TEST); - const char *scale_method_env = SDL20_getenv("SDL12COMPAT_SCALE_METHOD"); + const char *scale_method_env = SDL12Compat_GetHint("SDL12COMPAT_SCALE_METHOD"); const SDL_bool want_nearest = (scale_method_env && !SDL20_strcmp(scale_method_env, "nearest"))? SDL_TRUE : SDL_FALSE; int physical_w, physical_h; GLfloat clearcolor[4]; @@ -7297,7 +7411,7 @@ InitializeCDSubsystem(void) return; } - cdpath = SDL20_getenv("SDL12COMPAT_FAKE_CDROM_PATH"); + cdpath = SDL12Compat_GetHint("SDL12COMPAT_FAKE_CDROM_PATH"); if (cdpath) { CDRomPath = SDL_strdup(cdpath); } diff --git a/src/SDL20_include_wrapper.h b/src/SDL20_include_wrapper.h index eadf49732..361a1fcfc 100644 --- a/src/SDL20_include_wrapper.h +++ b/src/SDL20_include_wrapper.h @@ -110,6 +110,7 @@ #endif #ifdef __OS2__ #define INCL_DOSMODULEMGR /* for Dos_LoadModule() & co. */ +#define INCL_DOSPROCESS #endif #define __BUILDING_SDL12_COMPAT__ 1 From d2ebf173760b42e43d7ae8386fff51eb737be859 Mon Sep 17 00:00:00 2001 From: David Gow Date: Thu, 17 Mar 2022 21:42:29 +0800 Subject: [PATCH 229/606] Add a new quirk to work around context issues in Awesomenauts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit See bug #168. Awesomenauts sometimes calls glXMakeCurrent(NULL) for the rendering thread, including just before calling SDL_GL_SwapBuffers(). This hint just makes the default SDL context current on every call to SDL_GL_SwapBuffers(), which seems to work, even if it is somewhat worrying. (How this worked on SDL 1.2, I don't know…) --- src/SDL12_compat.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index ee6ed6a47..c285842e2 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -968,6 +968,7 @@ static GLuint OpenGLLogicalScalingMultisampleColor = 0; static GLuint OpenGLLogicalScalingMultisampleDepth = 0; static GLuint OpenGLCurrentReadFBO = 0; static GLuint OpenGLCurrentDrawFBO = 0; +static SDL_bool ForceGLSwapBufferContext = SDL_FALSE; /* !!! FIXME: need a mutex for the event queue. */ #define SDL12_MAXEVENTS 128 @@ -1138,6 +1139,7 @@ static QuirkEntryType quirks[] = { /* Awesomenauts uses Cg, and does weird things with the GL context. */ {"Awesomenauts.bin.x86", "SDL12COMPAT_OPENGL_SCALING", "0"}, {"Awesomenauts.bin.x86", "SDL_VIDEODRIVER", "x11"}, + {"Awesomenauts.bin.x86", "SDL12COMPAT_FORCE_GL_SWAPBUFFER_CONTEXT", "1"}, /* Braid uses Cg, which uses glXGetProcAddress(). */ {"braid", "SDL_VIDEODRIVER", "x11"}, @@ -5098,6 +5100,8 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12) fix_bordless_fs_win = SDL12Compat_GetHintBoolean("SDL12COMPAT_FIX_BORDERLESS_FS_WIN", fix_bordless_fs_win); + ForceGLSwapBufferContext = SDL12Compat_GetHintBoolean("SDL12COMPAT_FORCE_GL_SWAPBUFFER_CONTEXT", SDL_FALSE); + FIXME("currently ignores SDL_WINDOWID, which we could use with SDL_CreateWindowFrom ...?"); flags12 &= ~SDL12_HWACCEL; /* just in case - https://github.com/libsdl-org/SDL-1.2/issues/817 */ @@ -6710,6 +6714,11 @@ DECLSPEC void SDLCALL SDL_GL_SwapBuffers(void) { if (VideoWindow20) { + /* Some applications, e.g. Awesomenauts, play with glXMakeCurrent() behind out backs and break SwapBuffers() */ + if (ForceGLSwapBufferContext) { + SDL20_GL_MakeCurrent(VideoWindow20, VideoGLContext20); + } + if (OpenGLLogicalScalingFBO != 0) { const GLboolean has_scissor = OpenGLFuncs.glIsEnabled(GL_SCISSOR_TEST); const char *scale_method_env = SDL12Compat_GetHint("SDL12COMPAT_SCALE_METHOD"); From 558be82b237c02bad290bc8b0e083166fadcc6b6 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 18 Mar 2022 07:41:21 -0700 Subject: [PATCH 230/606] Fixed comment typo --- src/SDL12_compat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index c285842e2..4c132c734 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -6714,7 +6714,7 @@ DECLSPEC void SDLCALL SDL_GL_SwapBuffers(void) { if (VideoWindow20) { - /* Some applications, e.g. Awesomenauts, play with glXMakeCurrent() behind out backs and break SwapBuffers() */ + /* Some applications, e.g. Awesomenauts, play with glXMakeCurrent() behind our backs and break SwapBuffers() */ if (ForceGLSwapBufferContext) { SDL20_GL_MakeCurrent(VideoWindow20, VideoGLContext20); } From c08447e6dca1f01856f48222233c0f99dc3df7aa Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Fri, 18 Mar 2022 20:03:28 +0300 Subject: [PATCH 231/606] GetExeName() tidy-ups. --- src/SDL12_compat.c | 54 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 40 insertions(+), 14 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 4c132c734..1cf39fa97 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -59,10 +59,23 @@ #define SDL_BlitSurface SDL_UpperBlit -#ifdef __LINUX__ +#ifdef __linux__ #include /* for readlink() */ #endif +#if defined(__unix__) || defined(__APPLE__) +#ifndef PATH_MAX +#define PATH_MAX 1024 +#endif +#define SDL12_MAXPATH PATH_MAX +#elif defined _WIN32 +#define SDL12_MAXPATH MAX_PATH +#elif defined __OS2__ +#define SDL12_MAXPATH CCHMAXPATH +#else +#define SDL12_MAXPATH 1024 +#endif + #ifdef __cplusplus extern "C" { #endif @@ -1157,25 +1170,38 @@ static QuirkEntryType quirks[] = { #endif }; +#ifdef __linux__ +static void OS_GetExeName(char *buf, const unsigned maxpath) { + buf[0] = '\0'; + readlink("/proc/self/exe", buf, maxpath); +} +#elif defined(_WIN32) +static void OS_GetExeName(char *buf, const unsigned maxpath) { + buf[0] = '\0'; + GetModuleFileName(NULL, buf, maxpath); +} +#elif defined(__OS2__) +static void OS_GetExeName(char *buf, const unsigned maxpath) { + PPIB pib; + DosGetInfoBlocks(NULL, &pib); + buf[0] = '\0'; + DosQueryModuleName(pib->pib_hmte, maxpath, buf); +} +#else /* FIXME */ +static void OS_GetExeName(char *buf, const unsigned maxpath) { + buf[0] = '\0'; + (void)maxpath; +} +#endif + static const char * SDL12Compat_GetExeName(void) { static const char *exename = NULL; if (exename == NULL) { - static char path_buf[260]; + static char path_buf[SDL12_MAXPATH]; static char *base_path; -#ifdef _WIN32 - GetModuleFileName(NULL, path_buf, 260); -#elif defined(__linux__) - readlink("/proc/self/exe", path_buf, 260); -#elif defined(__OS2__) - PTIB tib; - PPIB pib; - DosGetInfoBlocks(&tib, &pib); - DosQueryModuleName(pib->pib_hmte, 260, path_buf); -#else - path_buf[0] = '\0'; -#endif + OS_GetExeName(path_buf, SDL12_MAXPATH); base_path = SDL20_strrchr(path_buf, *DIRSEP); if (base_path) { /* We have a '\\' component. */ From 3e909affb6165740d1e451f6ddd6146cd84bcfd8 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 18 Mar 2022 14:20:51 -0400 Subject: [PATCH 232/606] README: Better instructions on building for other CPU architectures. Fixes #173. --- README.md | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/README.md b/README.md index 1702b34dc..e650dfacc 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,13 @@ manager. Windows and Mac users can download prebuilt binaries from [SDL's download page](https://libsdl.org/download-2.0.php); make sure you get the "development libraries" and not "runtime binaries" there. +Linux users might need some packages from their Linux distribution. On Ubuntu, +you might need to do: + +```bash +sudo apt-get install build-essential cmake libsdl2-2.0-0 libsdl2-dev libgl-dev +``` + Now just point CMake at sdl12-compat's directory. Here's a command-line example: @@ -79,6 +86,50 @@ When the build is complete, you'll have a shared library you can drop in as a replacement for an existing SDL 1.2 build. This will also build the original SDL 1.2 test apps, so you can verify the library is working. + +# Building for older CPU architectures on Linux: + +There are a lot of binaries from many years ago that used SDL 1.2, which is +to say they are for CPU architectures that are likely not your current +system's. + +If you want to build a 32-bit x86 library on an x86-64 Linux machine, for +compatibility with older games, you should install some basic 32-bit +development libraries for your distribution. On Ubuntu, this would be: + + +```bash +sudo apt-get install gcc-multilib libsdl2-dev:i386 +``` + +...and then add `-m32` to your build options: + + +```bash +cd sdl12-compat +cmake -Bbuild32 -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_FLAGS=-m32 +cmake --build build32 +``` + + +# Building for older CPU architectures on macOS: + +macOS users can try adding `-DCMAKE_OSX_ARCHITECTURES='arm64;x86_64'` instead +of `-DCMAKE_C_FLAGS=-m32` to make a Universal Binary for both 64-bit Intel and +Apple Silicon machines. If you have an older (or much older!) version of Xcode, +you can try to build with "i386" or maybe even "powerpc" for 32-bit Intel or +PowerPC systems, but Xcode (and macOS itself) has not supported either of +these for quite some time, and you will likely struggle to get SDL2 to compile +here in small ways, as well...but with some effort, it's maybe _possible_ to +run SDL2 and sdl12-compat on Apple's abandoned architectures. + + +# Building for older CPU architectures on Windows: + +Windows users just select a 32-bit version of Visual Studio when running +CMake, when it asks you what compiler to target in the CMake GUI. + + # Configuration options: sdl12-compat has a number of configuration options which can be used to work From 44cf693ee5600493d33f9e6d7a1935e6b1783b7f Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Fri, 18 Mar 2022 23:51:56 +0300 Subject: [PATCH 233/606] added paranoid safety checks to SDL12Compat_GetExeName() result. --- src/SDL12_compat.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 1cf39fa97..5d76dc174 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1157,7 +1157,7 @@ static QuirkEntryType quirks[] = { /* Braid uses Cg, which uses glXGetProcAddress(). */ {"braid", "SDL_VIDEODRIVER", "x11"}, {"braid", "SDL12COMPAT_OPENGL_SCALING", "0"}, - + /* GOG's DOSBox builds have architecture-specific filenames. */ {"dosbox", "SDL12COMPAT_USE_KEYBOARD_LAYOUT", "0"}, {"dosbox_i686", "SDL12COMPAT_USE_KEYBOARD_LAYOUT", "0"}, @@ -1166,7 +1166,7 @@ static QuirkEntryType quirks[] = { /* TODO: Add any quirks needed for this system. */ /* A dummy entry to keep compilers happy. */ - {"", "", NULL} + {"", "", "0"} #endif }; @@ -1220,7 +1220,7 @@ SDL12Compat_GetHint(const char *name) const char *value; const char *exe_name; int i; - + /* First, check if there's an environment variable override. */ value = SDL20_getenv(name); if (value) { @@ -1229,6 +1229,10 @@ SDL12Compat_GetHint(const char *name) /* Else, look up the quirks table. */ exe_name = SDL12Compat_GetExeName(); + if (*exe_name == '\0') { + return NULL; + } + for (i = 0; i < SDL_arraysize(quirks); i++) { if (!SDL20_strcmp(exe_name, quirks[i].exe_name)) { if (!SDL20_strcmp(name, quirks[i].hint_name)) { @@ -1259,6 +1263,9 @@ SDL12Compat_PrintQuirks(void) int i; const char *exe_name = SDL12Compat_GetExeName(); + if (*exe_name == '\0') { + return; + } for (i = 0; i < SDL_arraysize(quirks); i++) { if (!SDL20_strcmp(exe_name, quirks[i].exe_name)) { if (!SDL20_getenv(quirks[i].hint_name)) { From e5e378a8b6c60c63b13ffbc10414c1ac2ac47c5a Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sat, 19 Mar 2022 03:29:24 +0300 Subject: [PATCH 234/606] OS_GetExeName(_WIN32): explicitly use GetModuleFileNameA just in case someone tries to be cute... --- src/SDL12_compat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 5d76dc174..114313b00 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1178,7 +1178,7 @@ static void OS_GetExeName(char *buf, const unsigned maxpath) { #elif defined(_WIN32) static void OS_GetExeName(char *buf, const unsigned maxpath) { buf[0] = '\0'; - GetModuleFileName(NULL, buf, maxpath); + GetModuleFileNameA(NULL, buf, maxpath); } #elif defined(__OS2__) static void OS_GetExeName(char *buf, const unsigned maxpath) { From 85d1f7ab0e22cdd526eb2ebf6021f247d9f55a3e Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sun, 20 Mar 2022 17:00:02 +0300 Subject: [PATCH 235/606] recommand using of absolute paths for SDL12COMPAT_FAKE_CDROM_PATH. Closes https://github.com/libsdl-org/sdl12-compat/pull/174 --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e650dfacc..6e0c19585 100644 --- a/README.md +++ b/README.md @@ -154,7 +154,8 @@ The available options are: - SDL12COMPAT_FAKE_CDROM_PATH: A path to a directory containing MP3 files (named trackXX.mp3, where XX is a two-digit track number) to be used by applications which play - CD audio. + CD audio. Using an absolute path is recommended: relative paths are + not guaranteed to work correctly. - SDL12COMPAT_OPENGL_SCALING: Enables scaling of OpenGL applications to the current desktop resolution. From 959df05af31602ccddbd47d91d9bbaaf819714cb Mon Sep 17 00:00:00 2001 From: David Gow Date: Sun, 20 Mar 2022 18:18:47 +0800 Subject: [PATCH 236/606] Fake SDL_INIT_EVENTTHREAD by pumping events in SDL_PeepEvents() sdl12-compat doesn't actually implement an event thread, but some games will only call SDL_PeepEvents(), which doesn't otherwise pump events, and get stuck when they've consumed all the events. Just pumping the event loop in SDL_PeepEvents() simulates an event thread well enough for most things. --- src/SDL12_compat.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 114313b00..3e130e2ae 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -952,6 +952,7 @@ static SDL_bool TranslateKeyboardLayout = SDL_FALSE; #endif static int VideoDisplayIndex = 0; static SDL_bool SupportSysWM = SDL_FALSE; +static SDL_bool EventThreadEnabled = SDL_FALSE; static SDL_bool CDRomInit = SDL_FALSE; static char *CDRomPath = NULL; static SDL12_CD *CDRomDevice = NULL; @@ -1997,7 +1998,6 @@ SDL_InitSubSystem(Uint32 sdl12flags) SDL20_setenv("SDL_VIDEODRIVER", forcevideodrv, 1); } - FIXME("support SDL_INIT_EVENTTHREAD where it makes sense?"); #define SETFLAG(flag) if (sdl12flags & SDL12_INIT_##flag) sdl20flags |= SDL_INIT_##flag SETFLAG(TIMER); SETFLAG(AUDIO); @@ -2017,6 +2017,9 @@ SDL_InitSubSystem(Uint32 sdl12flags) if (Init12Video() < 0) { rc = -1; } + + /* SDL_INIT_EVENTTHREAD takes effect when SDL_INIT_VIDEO is also set */ + EventThreadEnabled = (sdl12flags & SDL12_INIT_EVENTTHREAD) ? SDL_TRUE : SDL_FALSE; } #ifdef __WINDOWS__ @@ -2128,6 +2131,9 @@ SDL_QuitSubSystem(Uint32 sdl12flags) if (sdl12flags & SDL12_INIT_VIDEO) { Quit12Video(); + + /* Shutdown the fake event thread. */ + EventThreadEnabled = SDL_FALSE; } SDL20_QuitSubSystem(sdl20flags); @@ -2268,6 +2274,17 @@ SDL_PeepEvents(SDL12_Event *events12, int numevents, SDL_eventaction action, Uin { SDL12_Event dummy_event; + /* We don't actually implement an event thread in sdl12-compat, but some + * games will only call SDL_PeepEvents(), which doesn't otherwise pump + * events, and get stuck when they've consumed all the events. + * + * Just pumping the event loop here simulates an event thread well enough + * for most things. + */ + if (EventThreadEnabled) { + SDL_PumpEvents(); + } + if (action == SDL_ADDEVENT) { int i; for (i = 0; i < numevents; i++) { From 514ad86a05ac68b316b43f08315a14ee070aafa5 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 23 Mar 2022 17:16:25 -0400 Subject: [PATCH 237/606] SDL_FreeYUVOverlay: Abandon any queued draw of the freed overlay. Reference #176. --- src/SDL12_compat.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 3e130e2ae..d9788a6ef 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -6630,6 +6630,9 @@ DECLSPEC void SDLCALL SDL_FreeYUVOverlay(SDL12_Overlay *overlay12) { if (overlay12) { + if (QueuedDisplayOverlay12 == overlay12) { + QueuedDisplayOverlay12 = NULL; + } SDL12_YUVData *hwdata = (SDL12_YUVData *) overlay12->hwdata; SDL20_DestroyTexture(hwdata->texture20); SDL20_free(hwdata->pixelbuf); From 5ccf36fd0b430b48274e7d149494e6b3c7983de1 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Thu, 24 Mar 2022 00:33:50 +0300 Subject: [PATCH 238/606] fixed build ( -Werror=declaration-after-statement ) --- src/SDL12_compat.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index d9788a6ef..05004f340 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -6630,10 +6630,11 @@ DECLSPEC void SDLCALL SDL_FreeYUVOverlay(SDL12_Overlay *overlay12) { if (overlay12) { + SDL12_YUVData *hwdata; if (QueuedDisplayOverlay12 == overlay12) { QueuedDisplayOverlay12 = NULL; } - SDL12_YUVData *hwdata = (SDL12_YUVData *) overlay12->hwdata; + hwdata = (SDL12_YUVData *) overlay12->hwdata; SDL20_DestroyTexture(hwdata->texture20); SDL20_free(hwdata->pixelbuf); SDL20_free(overlay12); From 8287b5b103a72566986d0045f11cd085b64c8044 Mon Sep 17 00:00:00 2001 From: David Gow Date: Tue, 29 Mar 2022 16:42:10 +0800 Subject: [PATCH 239/606] quirk: Disable SDL_QuitSubsystem(SDL_INIT_VIDEO) for Multiwinia/steam MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For some reason, the Steam build of Multiwinia seems to be missing a call to SDL_Init() where the (older) non-Steam builds have one. This results in the game, when a resolution change is requested: - Calling SDL_QuitSubsystem(SDL_INIT_VIDEO) when the old window is destroyed. - NOT calling SDL_Init(SDL_INIT_VIDEO) when creating the new window. - Calling SDL_GetVideoInfo(), and promptly asserting when NULL is returned. - (And then proceed to create a window, which will fail, etc…) This issue _is_ reproducable under real SDL 1.2 (though with SDL_VIDEO_FULLSCREEN_HEAD set, no other modes are listed, so it's difficult to trigger), but it seemed worth working around. To do so, simply make SDL_QuitSubsystem() mask out SDL_INIT_VIDEO. This is hidden behind a new SDL12COMPAT_NO_QUIT_VIDEO hint, which is enabled by a quirk for "multiwinia.bin.x86". The various non-steam builds of the game do have the appropriate call to SDL_Init(), and the Steam build is 32-bit only, so we only activate this hack for the 32-bit builds. Steam App ID: 1530 Steam Build ID: 4497829 --- src/SDL12_compat.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 05004f340..218942770 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1162,7 +1162,10 @@ static QuirkEntryType quirks[] = { /* GOG's DOSBox builds have architecture-specific filenames. */ {"dosbox", "SDL12COMPAT_USE_KEYBOARD_LAYOUT", "0"}, {"dosbox_i686", "SDL12COMPAT_USE_KEYBOARD_LAYOUT", "0"}, - {"dosbox_x86_64", "SDL12COMPAT_USE_KEYBOARD_LAYOUT", "0"} + {"dosbox_x86_64", "SDL12COMPAT_USE_KEYBOARD_LAYOUT", "0"}, + + /* The 32-bit Steam build only of Multiwinia Quits but doesn't re-Init */ + {"multiwinia.bin.x86", "SDL12COMPAT_NO_QUIT_VIDEO", "1"} #else /* TODO: Add any quirks needed for this system. */ @@ -2119,6 +2122,14 @@ DECLSPEC void SDLCALL SDL_QuitSubSystem(Uint32 sdl12flags) { Uint32 sdl20flags, extraflags; + + /* Some games (notably the Steam build of Multiwinia), will + * SDL_Quit(SDL_INIT_VIDEO) on resolution change, and never call + * SDL_Init() again before creating their new window. + */ + if (SDL12Compat_GetHintBoolean("SDL12COMPAT_NO_QUIT_VIDEO", SDL_FALSE)) { + sdl12flags &= ~SDL12_INIT_VIDEO; + } InitFlags12to20(sdl12flags, &sdl20flags, &extraflags); if (extraflags & SDL12_INIT_CDROM) { From 022d9933c45f9133f68fab727f6ab46eff8faec6 Mon Sep 17 00:00:00 2001 From: David Gow Date: Tue, 29 Mar 2022 16:09:18 +0800 Subject: [PATCH 240/606] Update fake modes list to match SDL2 wayland SDL2's wayland backend has added support for fake resolutions in https://github.com/libsdl-org/SDL/pull/5466 sdl12-compat had a much smaller list of emulated modes, used when Logical Scaling was enabled. While, with Wayland now exposing these modes, including them in sdl12-compat's list is no longer required under Wayland, we might as well have the same list for any non-wayland platforms which might have similar issues. --- src/SDL12_compat.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 218942770..0b13d95c9 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1772,10 +1772,34 @@ AddVidModeToList(VideoModeList *vmode, SDL12_Rect *mode) /* A list of fake video modes which are included. */ static SDL12_Rect fake_modes[] = { + { 0, 0, 7680, 4320 }, + { 0, 0, 6144, 3160 }, + { 0, 0, 5120, 2880 }, + { 0, 0, 4096, 2304 }, + { 0, 0, 3840, 2160 }, + { 0, 0, 3200, 1800 }, + { 0, 0, 2880, 1600 }, + { 0, 0, 2560, 1600 }, + { 0, 0, 2048, 1536 }, + { 0, 0, 1920, 1440 }, + { 0, 0, 1920, 1200 }, { 0, 0, 1920, 1080 }, + { 0, 0, 1680, 1050 }, + { 0, 0, 1600, 1200 }, + { 0, 0, 1600, 900 }, + { 0, 0, 1440, 1080 }, + { 0, 0, 1440, 900 }, + { 0, 0, 1400, 1050 }, + { 0, 0, 1368, 768 }, + { 0, 0, 1280, 1024 }, + { 0, 0, 1280, 960 }, + { 0, 0, 1280, 800 }, { 0, 0, 1280, 720 }, + { 0, 0, 1152, 864 }, { 0, 0, 1024, 768 }, + { 0, 0, 864, 486 }, { 0, 0, 800, 600 }, + { 0, 0, 720, 480 }, { 0, 0, 640, 480 } }; From 49e6ea8a8327a311edd5eddf3ebfd13da53b1cd5 Mon Sep 17 00:00:00 2001 From: nia Date: Fri, 1 Apr 2022 09:08:43 +0200 Subject: [PATCH 241/606] BSD support: Don't assume presence of libdl on Unix Most non-Linux OSes have dlopen() in libc, and CMake provides a convenient variable for making use of libdl conditional. Signed-off-by: Nia Alarie --- CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0e96b6b07..e7a847cd7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -71,7 +71,7 @@ string(STRIP "${CMAKE_C_FLAGS}" CMAKE_C_FLAGS) if(UNIX AND NOT APPLE) set_target_properties(SDL PROPERTIES COMPILE_DEFINITIONS "_REENTRANT") - target_link_libraries(SDL PRIVATE dl) + target_link_libraries(SDL PRIVATE ${CMAKE_DL_LIBS}) endif() if(APPLE) set_target_properties(SDL PROPERTIES INSTALL_NAME_DIR "") @@ -254,7 +254,7 @@ if(SDL12DEVEL) set(SDL_CFLAGS "-D_GNU_SOURCE=1 -D_REENTRANT") set(SDL_RLD_FLAGS "") # !!! FIXME: this forces rpath, which we might want? set(SDL_LIBS "-lSDL") - set(SDL_STATIC_LIBS "-ldl") + set(SDL_STATIC_LIBS ${CMAKE_DL_LIBS}) if(NOT STATICDEVEL) set(SDL_STATIC_LIBS "") endif() @@ -297,7 +297,7 @@ if(STATICDEVEL AND SDL12DEVEL) add_library(SDL-static STATIC ${SDL12COMPAT_SRCS}) target_include_directories(SDL-static PRIVATE ${SDL2_INCLUDE_DIRS}) set_target_properties(SDL-static PROPERTIES COMPILE_DEFINITIONS "_REENTRANT") - target_link_libraries(SDL-static PRIVATE dl) + target_link_libraries(SDL-static PRIVATE ${CMAKE_DL_LIBS}) set_target_properties(SDL-static PROPERTIES VERSION "${PROJECT_VERSION}" OUTPUT_NAME "SDL") From 3f496287f50f3ca14916cc6e0ab6f3b2a4548366 Mon Sep 17 00:00:00 2001 From: nia Date: Fri, 1 Apr 2022 09:10:45 +0200 Subject: [PATCH 242/606] BSD support: Don't assume alloca.h is available on Unix BSDs have alloca() defined in stdlib.h. It's in alloca.h on Linux and illumos. Signed-off-by: Nia Alarie --- include/SDL/SDL_config.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/SDL/SDL_config.h b/include/SDL/SDL_config.h index dac480d5d..7b832a0e8 100644 --- a/include/SDL/SDL_config.h +++ b/include/SDL/SDL_config.h @@ -59,7 +59,6 @@ has these C runtime functions available. We're trying to avoid a configure stage, though. Send patches if your platform lacks something. */ #ifndef _WIN32 #define HAVE_LIBC 1 -#define HAVE_ALLOCA_H 1 #define HAVE_SYS_TYPES_H 1 #define HAVE_STDIO_H 1 #define STDC_HEADERS 1 @@ -72,6 +71,10 @@ stage, though. Send patches if your platform lacks something. */ #define HAVE_MATH_H 1 #endif +#if defined(__linux__) || defined(__sun) +#define HAVE_ALLOCA_H 1 +#endif + #if defined(__unix__) || defined(__APPLE__) #define HAVE_ICONV_H 1 #define HAVE_SIGNAL_H 1 From dcfc0736ebdffdccba642099c2220eab24812d0e Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Fri, 8 Apr 2022 11:55:10 +0300 Subject: [PATCH 243/606] remove unused math functions in dr_mp3.h (c.f. https://github.com/mackron/dr_libs/pull/228) --- src/dr_mp3.h | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/src/dr_mp3.h b/src/dr_mp3.h index dad327cc1..d145f5c3c 100644 --- a/src/dr_mp3.h +++ b/src/dr_mp3.h @@ -2424,10 +2424,6 @@ DRMP3_API void drmp3dec_f32_to_s16(const float *in, drmp3_int16 *out, size_t num Main Public API ************************************************************************************************************************************************************/ -#if 0 /* not used. */ -#include /* For sin() and exp(). */ -#endif - #if defined(SIZE_MAX) #define DRMP3_SIZE_MAX SIZE_MAX #else @@ -2491,25 +2487,6 @@ static DRMP3_INLINE drmp3_uint32 drmp3_gcf_u32(drmp3_uint32 a, drmp3_uint32 b) return a; } -#if 0 /* not used. */ -static DRMP3_INLINE double drmp3_sin(double x) -{ - /* TODO: Implement custom sin(x). */ - return sin(x); -} - -static DRMP3_INLINE double drmp3_exp(double x) -{ - /* TODO: Implement custom exp(x). */ - return exp(x); -} - -static DRMP3_INLINE double drmp3_cos(double x) -{ - return drmp3_sin((DRMP3_PI_D*0.5) - x); -} -#endif - static void* drmp3__malloc_default(size_t sz, void* pUserData) { (void)pUserData; From 999fa526f0b88caa04f68aa80cb2bb7f052e5020 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Fri, 8 Apr 2022 11:55:10 +0300 Subject: [PATCH 244/606] tweak DRMP3_INLINE macro for gcc (see: https://github.com/mackron/dr_libs/pull/230) --- src/dr_mp3.h | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/dr_mp3.h b/src/dr_mp3.h index d145f5c3c..1c8198dcb 100644 --- a/src/dr_mp3.h +++ b/src/dr_mp3.h @@ -232,19 +232,16 @@ typedef drmp3_int32 drmp3_result; #ifdef _MSC_VER #define DRMP3_INLINE __forceinline -#elif defined(__GNUC__) +#elif (defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 2))) || defined(__clang__) /* I've had a bug report where GCC is emitting warnings about functions possibly not being inlineable. This warning happens when the __attribute__((always_inline)) attribute is defined without an "inline" statement. I think therefore there must be some case where "__inline__" is not always defined, thus the compiler emitting these warnings. When using -std=c89 or -ansi on the - command line, we cannot use the "inline" keyword and instead need to use "__inline__". In an attempt to work around this issue - I am using "__inline__" only when we're compiling in strict ANSI mode. + command line, we cannot use the "inline" keyword and instead need to use "__inline__". */ - #if defined(__STRICT_ANSI__) - #define DRMP3_INLINE __inline__ __attribute__((always_inline)) - #else - #define DRMP3_INLINE inline __attribute__((always_inline)) - #endif + #define DRMP3_INLINE __inline__ __attribute__((always_inline)) +#elif defined(__GNUC__) + #define DRMP3_INLINE __inline__ #elif defined(__WATCOMC__) #define DRMP3_INLINE __inline #else From 2cca65787edb5b45cedc6ccbfa5104f95e91d16c Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sun, 10 Apr 2022 04:10:28 +0300 Subject: [PATCH 245/606] dr_mp3.h: fix ARM64 builds with MSVC. Fixes: https://github.com/icculus/SDL_sound/issues/58 See: https://github.com/mackron/dr_libs/issues/229 --- src/dr_mp3.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dr_mp3.h b/src/dr_mp3.h index 1c8198dcb..52609bb9e 100644 --- a/src/dr_mp3.h +++ b/src/dr_mp3.h @@ -2117,7 +2117,7 @@ static void drmp3d_synth(float *xl, drmp3d_sample_t *dstl, int nch, float *lins) vst1_lane_s16(dstl + (49 + i)*nch, pcmb, 2); #endif #else - static const drmp3_f4 g_scale = { 1.0f/32768.0f, 1.0f/32768.0f, 1.0f/32768.0f, 1.0f/32768.0f }; + const drmp3_f4 g_scale = vdupq_n_f32(1.0f/32768.0f); a = DRMP3_VMUL(a, g_scale); b = DRMP3_VMUL(b, g_scale); #if DRMP3_HAVE_SSE From 09a3cec4eb4a256d717a107c5390cfad5542ce26 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sun, 10 Apr 2022 04:33:50 +0300 Subject: [PATCH 246/606] fix SSE2 builds after previous ARM NEON commit. --- src/dr_mp3.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/dr_mp3.h b/src/dr_mp3.h index 52609bb9e..22348b0bf 100644 --- a/src/dr_mp3.h +++ b/src/dr_mp3.h @@ -2117,7 +2117,11 @@ static void drmp3d_synth(float *xl, drmp3d_sample_t *dstl, int nch, float *lins) vst1_lane_s16(dstl + (49 + i)*nch, pcmb, 2); #endif #else +#if DRMP3_HAVE_SSE + static const drmp3_f4 g_scale = { 1.0f/32768.0f, 1.0f/32768.0f, 1.0f/32768.0f, 1.0f/32768.0f }; +#else /* NEON: */ const drmp3_f4 g_scale = vdupq_n_f32(1.0f/32768.0f); +#endif a = DRMP3_VMUL(a, g_scale); b = DRMP3_VMUL(b, g_scale); #if DRMP3_HAVE_SSE From 359cd5d59379b04f396b522f01fb69d8293b6398 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sun, 10 Apr 2022 14:00:04 +0300 Subject: [PATCH 247/606] dr_mp3.h: sync with mainstream --- src/dr_mp3.h | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/src/dr_mp3.h b/src/dr_mp3.h index 22348b0bf..6fcc7e8c7 100644 --- a/src/dr_mp3.h +++ b/src/dr_mp3.h @@ -1,6 +1,6 @@ /* MP3 audio decoder. Choice of public domain or MIT-0. See license statements at the end of this file. -dr_mp3 - v0.6.32 - 2021-12-11 +dr_mp3 - v0.6.33 - 2022-04-10 David Reid - mackron@gmail.com @@ -101,7 +101,7 @@ extern "C" { #define DRMP3_VERSION_MAJOR 0 #define DRMP3_VERSION_MINOR 6 -#define DRMP3_VERSION_REVISION 32 +#define DRMP3_VERSION_REVISION 33 #define DRMP3_VERSION_STRING DRMP3_XSTRINGIFY(DRMP3_VERSION_MAJOR) "." DRMP3_XSTRINGIFY(DRMP3_VERSION_MINOR) "." DRMP3_XSTRINGIFY(DRMP3_VERSION_REVISION) #include /* For size_t. */ @@ -232,16 +232,25 @@ typedef drmp3_int32 drmp3_result; #ifdef _MSC_VER #define DRMP3_INLINE __forceinline -#elif (defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 2))) || defined(__clang__) +#elif defined(__GNUC__) /* I've had a bug report where GCC is emitting warnings about functions possibly not being inlineable. This warning happens when the __attribute__((always_inline)) attribute is defined without an "inline" statement. I think therefore there must be some case where "__inline__" is not always defined, thus the compiler emitting these warnings. When using -std=c89 or -ansi on the - command line, we cannot use the "inline" keyword and instead need to use "__inline__". + command line, we cannot use the "inline" keyword and instead need to use "__inline__". In an attempt to work around this issue + I am using "__inline__" only when we're compiling in strict ANSI mode. */ - #define DRMP3_INLINE __inline__ __attribute__((always_inline)) -#elif defined(__GNUC__) - #define DRMP3_INLINE __inline__ + #if defined(__STRICT_ANSI__) + #define DRMP3_GNUC_INLINE_HINT __inline__ + #else + #define DRMP3_GNUC_INLINE_HINT inline + #endif + + #if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 2)) || defined(__clang__) + #define DRMP3_INLINE DRMP3_GNUC_INLINE_HINT __attribute__((always_inline)) + #else + #define DRMP3_INLINE DRMP3_GNUC_INLINE_HINT + #endif #elif defined(__WATCOMC__) #define DRMP3_INLINE __inline #else @@ -2117,11 +2126,11 @@ static void drmp3d_synth(float *xl, drmp3d_sample_t *dstl, int nch, float *lins) vst1_lane_s16(dstl + (49 + i)*nch, pcmb, 2); #endif #else -#if DRMP3_HAVE_SSE + #if DRMP3_HAVE_SSE static const drmp3_f4 g_scale = { 1.0f/32768.0f, 1.0f/32768.0f, 1.0f/32768.0f, 1.0f/32768.0f }; -#else /* NEON: */ + #else const drmp3_f4 g_scale = vdupq_n_f32(1.0f/32768.0f); -#endif + #endif a = DRMP3_VMUL(a, g_scale); b = DRMP3_VMUL(b, g_scale); #if DRMP3_HAVE_SSE @@ -2488,6 +2497,7 @@ static DRMP3_INLINE drmp3_uint32 drmp3_gcf_u32(drmp3_uint32 a, drmp3_uint32 b) return a; } + static void* drmp3__malloc_default(size_t sz, void* pUserData) { (void)pUserData; @@ -4480,6 +4490,11 @@ counts rather than sample counts. /* REVISION HISTORY ================ +v0.6.33 - 2022-04-10 + - Fix compilation error with the MSVC ARM64 build. + - Fix compilation error on older versions of GCC. + - Remove some unused functions. + v0.6.32 - 2021-12-11 - Fix a warning with Clang. From d399e9b03630a1d2445563e13ea17623a233a303 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Fri, 15 Apr 2022 01:24:40 +0300 Subject: [PATCH 248/606] clear PendingKeydownEvent upon video quit - just in case --- src/SDL12_compat.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 0b13d95c9..ff33fc208 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -2137,6 +2137,7 @@ Quit12Video(void) VideoInfoVfmt20 = NULL; EventFilter12 = NULL; EventQueueAvailable = EventQueueHead = EventQueueTail = NULL; + SDL20_memset(&PendingKeydownEvent, 0, sizeof(SDL12_Event)); SDL_FreeCursor(CurrentCursor12); VideoModes = NULL; VideoModesCount = 0; From 6ec51e6b9e2d2ebc2b7c39f22c44a5d581bdece1 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Fri, 15 Apr 2022 01:24:56 +0300 Subject: [PATCH 249/606] check for NULL VideoRenderer in PresentScreen() fixes segfault from tucnak. (ref. issue: #182.) --- src/SDL12_compat.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index ff33fc208..db22c30d8 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -5826,6 +5826,10 @@ SDL_DisplayFormatAlpha(SDL12_Surface *surface12) static void PresentScreen(void) { + if (!VideoRenderer20) { + return; + } + SDL20_RenderClear(VideoRenderer20); SDL20_RenderCopy(VideoRenderer20, VideoTexture20, NULL, NULL); From 940352955ffef7ab4113bc28a2454a8f66b8e3f7 Mon Sep 17 00:00:00 2001 From: David Gow Date: Mon, 2 May 2022 17:43:36 +0800 Subject: [PATCH 250/606] Use SDL_PIXELFORMAT_RGB888 for 24-bit surfaces We're currently using SDL_PIXELFORMAT_RGB24, which results in schismtracker being blue when resized (#183). While it's possible that RGB888 is wrong on big-endian systems, it at least matches what we do for 16-bit (RGB565) and 32-bit (XRGB8888) formats, so if we're wrong, we'll at least be consistently wrong. --- src/SDL12_compat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index db22c30d8..78e4d7e8a 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -5231,7 +5231,7 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12) switch (bpp) { case 8: appfmt = SDL_PIXELFORMAT_INDEX8; break; case 16: appfmt = SDL_PIXELFORMAT_RGB565; FIXME("bgr instead of rgb?"); break; - case 24: appfmt = SDL_PIXELFORMAT_RGB24; FIXME("bgr instead of rgb?"); break; + case 24: appfmt = SDL_PIXELFORMAT_RGB888; FIXME("bgr instead of rgb?"); break; case 32: appfmt = SDL_PIXELFORMAT_XRGB8888; FIXME("bgr instead of rgb?"); break; default: SDL20_SetError("Unsupported bits-per-pixel"); return NULL; } From 12294317ee19f6c102598e4c613c28a719a4534c Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Wed, 15 Jun 2022 17:21:34 -0700 Subject: [PATCH 251/606] SDL fixed the calling convention for math functions --- src/SDL20_syms.h | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/SDL20_syms.h b/src/SDL20_syms.h index 1393217d8..4121cc293 100644 --- a/src/SDL20_syms.h +++ b/src/SDL20_syms.h @@ -299,19 +299,9 @@ SDL20_SYM_PASSTHROUGH(size_t,iconv,(SDL_iconv_t a, const char **b, size_t *c, ch SDL20_SYM_PASSTHROUGH(char *,iconv_string,(const char *a, const char *b, const char *c, size_t d),(a,b,c,d),return) SDL20_SYM(int,setenv,(const char *a, const char *b, int c),(a,b,c),return) -#ifdef __WATCOMC__ /* Watcom builds are broken with SDL math functions. */ -#ifndef SDL12_MATH -#include -#define SDL20_fabs fabs -#define SDL20_ceil ceil -#define SDL20_floor floor -#define SDL12_MATH -#endif -#else SDL20_SYM(double,fabs,(double a),(a),return) SDL20_SYM(double,ceil,(double a),(a),return) SDL20_SYM(double,floor,(double a),(a),return) -#endif SDL20_SYM(SDL_Renderer *,CreateRenderer,(SDL_Window *a, int b, Uint32 c),(a,b,c),return) SDL20_SYM(int,GetRendererInfo,(SDL_Renderer *a, SDL_RendererInfo *b),(a,b),return) From d3bc7cdc0aede8e2f81898a849d26b80a7b3482c Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Tue, 12 Jul 2022 01:11:50 +0300 Subject: [PATCH 252/606] SDL_endian.h: check for __powerpc__ and __PPC__ in big endian decision. Also remove the _M_PPC check from there. Reference issue: https://github.com/libsdl-org/SDL/issues/5907 --- include/SDL/SDL_endian.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/SDL/SDL_endian.h b/include/SDL/SDL_endian.h index fb27d371e..24773f2aa 100644 --- a/include/SDL/SDL_endian.h +++ b/include/SDL/SDL_endian.h @@ -32,7 +32,7 @@ real SDL-1.2 available to you. */ #include #endif -/* This is all lifted out of SDL2's zlib-licensed headers. */ +/* These are all lifted out of SDL2's zlib-licensed headers. */ #define SDL_LIL_ENDIAN 1234 #define SDL_BIG_ENDIAN 4321 @@ -60,7 +60,7 @@ real SDL-1.2 available to you. */ #if defined(__hppa__) || \ defined(__m68k__) || defined(mc68000) || defined(_M_M68K) || \ (defined(__MIPS__) && defined(__MIPSEB__)) || \ - defined(__ppc__) || defined(__POWERPC__) || defined(_M_PPC) || \ + defined(__ppc__) || defined(__POWERPC__) || defined(__powerpc__) || defined(__PPC__) || \ defined(__sparc__) #define SDL_BYTEORDER SDL_BIG_ENDIAN #else From f38ee8ea172a2b156b95bc11d7646e7eeb7909a7 Mon Sep 17 00:00:00 2001 From: Aaron Barany Date: Wed, 27 Jul 2022 23:02:15 -0700 Subject: [PATCH 253/606] Avoid crash if NULL is passed to SDL_RemoveTimer. --- src/SDL12_compat.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 78e4d7e8a..45613181e 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -7101,8 +7101,8 @@ DECLSPEC SDL_bool SDLCALL SDL_RemoveTimer(SDL12_TimerID data) { /* !!! FIXME: 1.2 will safely return SDL_FALSE if this is a - * bogus timer. This code will dereference a bogus pointer. */ - const SDL_bool retval = SDL20_RemoveTimer(data->timer_id); + * bogus timer. This code will dereference a bogus pointer, though it handles NULL. */ + const SDL_bool retval = data ? SDL20_RemoveTimer(data->timer_id) : SDL_FALSE; if (retval) { SDL20_free(data); } From c59075cd443f82b31179d5f18602e78e5139d35b Mon Sep 17 00:00:00 2001 From: Aaron Barany Date: Thu, 28 Jul 2022 00:32:40 -0700 Subject: [PATCH 254/606] Use fallback for unicode on keydown when CTRL is pressed. Text events aren't sent when CTRL is pressed, causing applications that depend on it to ignore some keyboard commands. fixes #187 --- src/SDL12_compat.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 45613181e..1339644fd 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -4056,7 +4056,16 @@ EventFilter20to12(void *data, SDL_Event *event20) FlushPendingKeydownEvent(0x1B); /* '\e' */ break; default: - /* not a supported control character */ + /* not a supported control character + when CTRL is pressed, text events aren't sent so use fallback for unicode */ + if (PendingKeydownEvent.key.keysym.mod & KMOD_CTRL) { + const char *keyName = SDL_GetKeyName(PendingKeydownEvent.key.keysym.sym); + /* use key name as unicode if it's a single character */ + if (keyName[0] && !keyName[1]) + FlushPendingKeydownEvent(keyName[0]); + else + FlushPendingKeydownEvent(0); + } break; } From 1e87ef06eca93ce0c5cba73f5ec336de0f5a4fc0 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Thu, 28 Jul 2022 17:51:20 +0300 Subject: [PATCH 255/606] fix SYM_PASSTHROUGH for SDL_qsort --- src/SDL20_syms.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/SDL20_syms.h b/src/SDL20_syms.h index 4121cc293..92f22942e 100644 --- a/src/SDL20_syms.h +++ b/src/SDL20_syms.h @@ -260,7 +260,7 @@ SDL20_SYM_PASSTHROUGH(void *,calloc,(size_t a, size_t b),(a,b),return) SDL20_SYM_PASSTHROUGH(void *,realloc,(void *a, size_t b),(a,b),return) SDL20_SYM_PASSTHROUGH(void,free,(void *a),(a),) SDL20_SYM_PASSTHROUGH(char *,getenv,(const char *a),(a),return) -SDL20_SYM_PASSTHROUGH(void,qsort,(void *a, size_t b, size_t c, int (*d)(const void *, const void *)),(a,b,c,d),) +SDL20_SYM_PASSTHROUGH(void,qsort,(void *a, size_t b, size_t c, int (SDLCALL *d)(const void *, const void *)),(a,b,c,d),) SDL20_SYM_PASSTHROUGH(void *,memset,(void *a, int b, size_t c),(a,b,c),return) SDL20_SYM_PASSTHROUGH(void *,memcpy,(void *a, const void *b, size_t c),(a,b,c),return) SDL20_SYM(void *,memmove,(void *a, const void *b, size_t c),(a,b,c),return) @@ -392,4 +392,3 @@ OPENGL_EXT(GL_ARB_texture_non_power_of_two) #undef OPENGL_EXT /* vi: set ts=4 sw=4 expandtab: */ - From 6d68bff0e950be9c550f3b3bc60e6fa4a86edd7d Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sun, 31 Jul 2022 05:10:02 +0300 Subject: [PATCH 256/606] sync SDL_endian.h with mainstream SDL2. --- include/SDL/SDL_endian.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/SDL/SDL_endian.h b/include/SDL/SDL_endian.h index 24773f2aa..94cbb5161 100644 --- a/include/SDL/SDL_endian.h +++ b/include/SDL/SDL_endian.h @@ -41,7 +41,7 @@ real SDL-1.2 available to you. */ #ifdef __linux__ #include #define SDL_BYTEORDER __BYTE_ORDER -#elif defined(__OpenBSD__) +#elif defined(__OpenBSD__) || defined(__DragonFly__) #include #define SDL_BYTEORDER BYTE_ORDER #elif defined(__FreeBSD__) || defined(__NetBSD__) From b13166f31a1d1b315744e6cc45901173d99590c7 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 8 Aug 2022 11:02:38 -0400 Subject: [PATCH 257/606] syswm: Added a magic hack so apps can access actual SDL2 SysWM information. Fixes #186. --- CMakeLists.txt | 1 + include/SDL/SDL_syswm.h | 16 +++++ src/SDL12_compat.c | 127 +++++++++++++++++++++++++++++++++++++++- test/README | 1 + test/testsyswm2on12.c | 113 +++++++++++++++++++++++++++++++++++ 5 files changed, 257 insertions(+), 1 deletion(-) create mode 100644 test/testsyswm2on12.c diff --git a/CMakeLists.txt b/CMakeLists.txt index e7a847cd7..70cdb5a33 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -217,6 +217,7 @@ if(SDL12TESTS) test_program(torturethread "test/torturethread.c") test_program(testdyngl "test/testdyngl.c") test_program(testgl "test/testgl.c") + test_program(testsyswm2on12 "test/testsyswm2on12.c") if(OPENGL_FOUND) if(CMAKE_VERSION VERSION_LESS 3.10 OR NOT OPENGL_opengl_LIBRARY) target_link_libraries(testgl ${OPENGL_gl_LIBRARY}) diff --git a/include/SDL/SDL_syswm.h b/include/SDL/SDL_syswm.h index 007618d10..af1931126 100644 --- a/include/SDL/SDL_syswm.h +++ b/include/SDL/SDL_syswm.h @@ -120,6 +120,22 @@ real SDL-1.2 available to you. */ #include "begin_code.h" +/* SPECIAL CASE FOR SDL12-COMPAT: if version.major == 2, we'll fill in this struct with the native window handle. */ +/* This is not part of the real 1.2 API! */ +typedef struct SDL_SysWMinfo2on12 +{ + SDL_version version; + SDL_SYSWM_TYPE subsystem; + void *data1; + void *data2; + void *data3; + void *data4; + void *data5; + void *data6; + void *data7; + void *data8; +} SDL_SysWMinfo2on12; + extern DECLSPEC int SDLCALL SDL_GetWMInfo(SDL_SysWMinfo *info); #include "close_code.h" diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 1339644fd..022900341 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -641,6 +641,22 @@ typedef struct SDL12_SysWMinfo #endif } SDL12_SysWMinfo; +/* SPECIAL CASE FOR SDL12-COMPAT: if version.major == 2, we'll fill in this struct with the native window handle. */ +/* This is not part of the real 1.2 API! */ +typedef struct SDL12_SysWMinfo2on12 +{ + SDL_version version; + SDL12_SYSWM_TYPE subsystem; + void *data1; + void *data2; + void *data3; + void *data4; + void *data5; + void *data6; + void *data7; + void *data8; +} SDL12_SysWMinfo2on12; + typedef enum { @@ -6451,9 +6467,10 @@ SDL_GetWMInfo(SDL12_SysWMinfo *info12) SDL_SysWMinfo info20; SDL_bool temp_window = SDL_FALSE; SDL_Window *win20 = VideoWindow20; + const SDL_bool do_2on12 = ((info12->version.major == 2) && (info12->version.minor == 0) && (info12->version.major == 2) && (info12->version.patch == 0)); int rc; - if (info12->version.major > 1) { + if ((info12->version.major > 1) && !do_2on12) { SDL20_SetError("Requested version is unsupported"); return 0; /* some programs only test against 0, not -1 */ } else if (!SupportSysWM) { @@ -6482,6 +6499,114 @@ SDL_GetWMInfo(SDL12_SysWMinfo *info12) return 0; /* some programs only test against 0, not -1 */ } + /* SPECIAL CASE FOR SDL12-COMPAT: if version.major == 2, we'll fill in this struct with the native window handle. */ + if (do_2on12) { + SDL12_SysWMinfo2on12 *wminfo2 = (SDL12_SysWMinfo2on12 *) info12; + SDL_zerop(wminfo2); + SDL20_memcpy(&wminfo2->version, &info20.version, sizeof (wminfo2->version)); + wminfo2->subsystem = info20.subsystem; /* these do not map to SDL 1.2 values! You're on your own! */ + + switch (info20.subsystem) { + #if defined(SDL_VIDEO_DRIVER_WINDOWS) + case SDL_SYSWM_WINDOWS: + wminfo2->data1 = (void *) info20.info.win.window; + wminfo2->data2 = (void *) info20.info.win.hdc; + wminfo2->data3 = (void *) info20.info.win.hinstance; + break; + #endif + + #if defined(SDL_VIDEO_DRIVER_WINRT) + case SDL_SYSWM_WINRT: + wminfo2->data1 = (void *) info20.info.winrt.window; + break; + #endif + + #if defined(SDL_VIDEO_DRIVER_X11) + case SDL_SYSWM_X11: + wminfo2->data1 = (void *) info20.info.x11.display; + wminfo2->data2 = (void *) info20.info.x11.window; + break; + #endif + + #if defined(SDL_VIDEO_DRIVER_DIRECTFB) + case SDL_SYSWM_DIRECTFB: + wminfo2->data1 = (void *) info20.info.dfb.dfb; + wminfo2->data2 = (void *) info20.info.dfb.window; + wminfo2->data3 = (void *) info20.info.dfb.surface; + break; + #endif + + #if defined(SDL_VIDEO_DRIVER_COCOA) + case SDL_SYSWM_COCOA: + wminfo2->data1 = (void *) info20.info.cocoa.window; + break; + #endif + + #if defined(SDL_VIDEO_DRIVER_UIKIT) + case SDL_SYSWM_UIKIT: + wminfo2->data1 = (void *) info20.info.uikit.window; + wminfo2->data2 = (void *) info20.info.uikit.framebuffer; + wminfo2->data3 = (void *) info20.info.uikit.colorbuffer; + wminfo2->data4 = (void *) info20.info.uikit.resolveFramebuffer; + break; + #endif + + #if defined(SDL_VIDEO_DRIVER_WAYLAND) + case SDL_SYSWM_WAYLAND: + wminfo2->data1 = (void *) info20.info.wl.display; + wminfo2->data2 = (void *) info20.info.wl.surface; + wminfo2->data3 = (void *) info20.info.wl.shell_surface; + wminfo2->data4 = (void *) info20.info.wl.egl_window; + wminfo2->data5 = (void *) info20.info.wl.xdg_surface; + wminfo2->data6 = (void *) info20.info.wl.xdg_toplevel; + wminfo2->data7 = (void *) info20.info.wl.xdg_popup; + wminfo2->data8 = (void *) info20.info.wl.xdg_positioner; + break; + #endif + + #if defined(SDL_VIDEO_DRIVER_MIR) /* no longer available, left for API/ABI compatibility. Remove in 2.1! */ + case SDL_SYSWM_MIR: + wminfo2->data1 = (void *) info20.info.mir.connection; + wminfo2->data2 = (void *) info20.info.mir.surface; + break; + #endif + + #if defined(SDL_VIDEO_DRIVER_ANDROID) + case SDL_SYSWM_ANDROID: + wminfo2->data1 = (void *) info20.info.android.window; + wminfo2->data2 = (void *) info20.info.android.surface; + break; + #endif + + #if defined(SDL_VIDEO_DRIVER_OS2) + case SDL_SYSWM_OS2: + wminfo2->data1 = (void *) info20.info.os2.hwnd; + wminfo2->data2 = (void *) info20.info.os2.hwndFrame; + break; + #endif + + #if defined(SDL_VIDEO_DRIVER_VIVANTE) + case SDL_SYSWM_VIVANTE: + wminfo2->data1 = (void *) info20.info.vivante.display; + wminfo2->data2 = (void *) info20.info.vivante.window; + break; + #endif + + #if defined(SDL_VIDEO_DRIVER_KMSDRM) + case SDL_SYSWM_KMSDRM: + wminfo2->data1 = (void *) (size_t) info20.info.kmsdrm.dev_index; + wminfo2->data2 = (void *) (size_t) info20.info.kmsdrm.drm_fd; + wminfo2->data3 = (void *) (size_t) info20.info.kmsdrm.gbm_dev; + break; + #endif + + default: + return 0; + } + + return 1; + } + #if defined(SDL_VIDEO_DRIVER_WINDOWS) SDL_assert(info20.subsystem == SDL_SYSWM_WINDOWS); info12->window = temp_window ? 0 : info20.info.win.window; diff --git a/test/README b/test/README index e158b4e42..a77450a7b 100644 --- a/test/README +++ b/test/README @@ -33,3 +33,4 @@ These are test programs for the SDL library: testwm Test window manager -- title, icon, events threadwin Test multi-threaded event handling torturethread Simple test for thread creation/destruction + testsyswm2on12 Simple test for SDL_SysWM2on12 compatibility magic. \ No newline at end of file diff --git a/test/testsyswm2on12.c b/test/testsyswm2on12.c new file mode 100644 index 000000000..c4ee0dad2 --- /dev/null +++ b/test/testsyswm2on12.c @@ -0,0 +1,113 @@ +/* this isn't a classic SDL 1.2 test program, this tests a little + compatibility magic that only exists in sdl12-compat. */ + +#include +#include + +#include "SDL.h" +#include "SDL_syswm.h" + +/* so this will compile with classic 1.2 headers... */ +#ifndef SDL12_COMPAT_HEADERS +#include "begin_code.h" +typedef struct SDL_SysWMinfo2on12 +{ + SDL_version version; + SDL_SYSWM_TYPE subsystem; + void *data1; + void *data2; + void *data3; + void *data4; + void *data5; + void *data6; + void *data7; + void *data8; +} SDL_SysWMinfo2on12; +#include "end_code.h" +#endif + +typedef enum +{ + SDL20_SYSWM_UNKNOWN, + SDL20_SYSWM_WINDOWS, + SDL20_SYSWM_X11, + SDL20_SYSWM_DIRECTFB, + SDL20_SYSWM_COCOA, + SDL20_SYSWM_UIKIT, + SDL20_SYSWM_WAYLAND, + SDL20_SYSWM_MIR, + SDL20_SYSWM_WINRT, + SDL20_SYSWM_ANDROID, + SDL20_SYSWM_VIVANTE, + SDL20_SYSWM_OS2, + SDL20_SYSWM_HAIKU, + SDL20_SYSWM_KMSDRM, + SDL20_SYSWM_RISCOS +} SDL20_SYSWM_TYPE; + +static const char * +subsystem_name(const SDL20_SYSWM_TYPE typ) +{ + static char unrecognized[64]; + switch (typ) { + case SDL20_SYSWM_UNKNOWN: return "Unknown"; + case SDL20_SYSWM_WINDOWS: return "Windows"; + case SDL20_SYSWM_X11: return "X11"; + case SDL20_SYSWM_DIRECTFB: return "DirectFB"; + case SDL20_SYSWM_COCOA: return "Cocoa"; + case SDL20_SYSWM_UIKIT: return "UIKit"; + case SDL20_SYSWM_WAYLAND: return "Wayland"; + case SDL20_SYSWM_MIR: return "Mir"; + case SDL20_SYSWM_WINRT: return "WinRT"; + case SDL20_SYSWM_ANDROID: return "Android"; + case SDL20_SYSWM_VIVANTE: return "Vivante"; + case SDL20_SYSWM_OS2: return "OS/2"; + case SDL20_SYSWM_HAIKU: return "Haiku"; + case SDL20_SYSWM_KMSDRM: return "KMSDRM"; + case SDL20_SYSWM_RISCOS: return "RiscOS"; + default: break; + } + + snprintf(unrecognized, sizeof (unrecognized), "Unrecognized (%d)", (int) typ); + return unrecognized; +} + +int main(int argc, char **argv) +{ + SDL_SysWMinfo2on12 syswm_info; + + if (SDL_Init(SDL_INIT_VIDEO) < 0) { + fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError()); + return 1; + } + + if (SDL_SetVideoMode(640, 480, 32, 0) == NULL) { + fprintf(stderr, "Couldn't create an SDL window: %s\n", SDL_GetError()); + SDL_Quit(); + return 1; + } + + SDL_memset(&syswm_info, '\0', sizeof (syswm_info)); + syswm_info.version.major = 2; /* this triggers magic in sdl12-compat */ + + /* obviously this should fail with classic SDL 1.2. */ + if (SDL_GetWMInfo((SDL_SysWMinfo *) &syswm_info) != 1) { + fprintf(stderr, "Failed to get syswm 2on12 info: %s\n", SDL_GetError()); + } else { + printf("SysWM2on12 info:\n"); + printf("Version: %d.%d.%d\n", syswm_info.version.major, syswm_info.version.minor, syswm_info.version.patch); + printf("Subsystem: %s\n", subsystem_name(syswm_info.subsystem)); + printf("data1: %p\n", syswm_info.data1); + printf("data2: %p\n", syswm_info.data2); + printf("data3: %p\n", syswm_info.data3); + printf("data4: %p\n", syswm_info.data4); + printf("data5: %p\n", syswm_info.data5); + printf("data6: %p\n", syswm_info.data6); + printf("data7: %p\n", syswm_info.data7); + printf("data8: %p\n", syswm_info.data8); + } + + SDL_Quit(); + return 0; +} + From 4bfa4f9fbdee24fee3d009f870b7c025aac4cb36 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 8 Aug 2022 14:56:58 -0400 Subject: [PATCH 258/606] Patched to compile: SDL_SYSWM_TYPE isn't always available in 1.2. --- include/SDL/SDL_syswm.h | 2 +- src/SDL12_compat.c | 4 ++-- test/testsyswm2on12.c | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/SDL/SDL_syswm.h b/include/SDL/SDL_syswm.h index af1931126..2add7d9b7 100644 --- a/include/SDL/SDL_syswm.h +++ b/include/SDL/SDL_syswm.h @@ -125,7 +125,7 @@ real SDL-1.2 available to you. */ typedef struct SDL_SysWMinfo2on12 { SDL_version version; - SDL_SYSWM_TYPE subsystem; + Uint32 subsystem; void *data1; void *data2; void *data3; diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 022900341..523dfc339 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -646,7 +646,7 @@ typedef struct SDL12_SysWMinfo typedef struct SDL12_SysWMinfo2on12 { SDL_version version; - SDL12_SYSWM_TYPE subsystem; + Uint32 subsystem; void *data1; void *data2; void *data3; @@ -6504,7 +6504,7 @@ SDL_GetWMInfo(SDL12_SysWMinfo *info12) SDL12_SysWMinfo2on12 *wminfo2 = (SDL12_SysWMinfo2on12 *) info12; SDL_zerop(wminfo2); SDL20_memcpy(&wminfo2->version, &info20.version, sizeof (wminfo2->version)); - wminfo2->subsystem = info20.subsystem; /* these do not map to SDL 1.2 values! You're on your own! */ + wminfo2->subsystem = (Uint32) info20.subsystem; /* these do not map to SDL 1.2 values! You're on your own! */ switch (info20.subsystem) { #if defined(SDL_VIDEO_DRIVER_WINDOWS) diff --git a/test/testsyswm2on12.c b/test/testsyswm2on12.c index c4ee0dad2..73b000df8 100644 --- a/test/testsyswm2on12.c +++ b/test/testsyswm2on12.c @@ -13,7 +13,7 @@ typedef struct SDL_SysWMinfo2on12 { SDL_version version; - SDL_SYSWM_TYPE subsystem; + Uint32 subsystem; void *data1; void *data2; void *data3; @@ -46,10 +46,10 @@ typedef enum } SDL20_SYSWM_TYPE; static const char * -subsystem_name(const SDL20_SYSWM_TYPE typ) +subsystem_name(const Uint32 typ) { static char unrecognized[64]; - switch (typ) { + switch ((SDL20_SYSWM_TYPE) typ) { case SDL20_SYSWM_UNKNOWN: return "Unknown"; case SDL20_SYSWM_WINDOWS: return "Windows"; case SDL20_SYSWM_X11: return "X11"; From b03ee58d6eddbd6f75d774e235b4b10ac6b6e355 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Mon, 8 Aug 2022 23:02:56 +0300 Subject: [PATCH 259/606] fix build using c++ compilers. --- src/SDL12_compat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 523dfc339..a607939d5 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -6467,7 +6467,7 @@ SDL_GetWMInfo(SDL12_SysWMinfo *info12) SDL_SysWMinfo info20; SDL_bool temp_window = SDL_FALSE; SDL_Window *win20 = VideoWindow20; - const SDL_bool do_2on12 = ((info12->version.major == 2) && (info12->version.minor == 0) && (info12->version.major == 2) && (info12->version.patch == 0)); + const int do_2on12 = ((info12->version.major == 2) && (info12->version.minor == 0) && (info12->version.major == 2) && (info12->version.patch == 0)); int rc; if ((info12->version.major > 1) && !do_2on12) { From 5f561733398692248b88661724ac9a9c0926fbf2 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sat, 13 Aug 2022 20:02:12 -0400 Subject: [PATCH 260/606] Reworked joystick support. This makes the joysticks consistent, as their device indexes won't change, like SDL 1.2 worked. Also, it can optionally use SDL2 game controllers for devices, which has some interesting tradeoffs. Reference issue #157. --- README.md | 12 ++ src/SDL12_compat.c | 411 +++++++++++++++++++++++++++++------- src/SDL20_include_wrapper.h | 31 +++ src/SDL20_syms.h | 33 ++- 4 files changed, 396 insertions(+), 91 deletions(-) diff --git a/README.md b/README.md index 6e0c19585..92168421a 100644 --- a/README.md +++ b/README.md @@ -196,6 +196,18 @@ The available options are: (in most applications) will take the keyboard layout into account regardless of this option. +- SDL12COMPAT_USE_GAME_CONTROLLERS: + Use SDL2's higher-level Game Controller API to expose joysticks instead of + its lower-level joystick API. The benefit of this is that you can exert + more control over arbitrary hardware (deadzones, button mapping, device + name, etc), and button and axes layouts are consistent (what is physically + located where an Xbox360's "A" button is will always be SDL 1.2 joystick + button 0, "B" will be 1, etc). The downside is it might not expose all of + a given piece of hardware's functionality, or simply not make sense in + general...if you need to use a flight stick, for example, you should not + use this hint. If there is no known game controller mapping for a joystick, + and this hint is in use, it will not be listed as an availble device. + - SDL_MOUSE_RELATIVE_SCALING: If enabled, relative mouse motion is scaled when the application is running at a non-native resolution. This may be required with some diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index a607939d5..fc97c14e1 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -888,9 +888,14 @@ typedef struct typedef struct { - int device_index; - SDL_Joystick *joystick; -} JoystickOpenedItem; + char *name; + SDL_atomic_t refcount; + SDL_JoystickID instance_id; + union { + SDL_Joystick *joystick; + SDL_GameController *controller; + } dev; +} SDL12_Joystick; /* this is identical to SDL2, except SDL2 forced the structure packing in some instances, so we can't passthrough without converting the struct. :( */ @@ -976,7 +981,9 @@ static SDL12_EventFilter EventFilter12 = NULL; static SDL12_Cursor *CurrentCursor12 = NULL; static Uint8 EventStates[SDL12_NUMEVENTS]; static int SwapInterval = 0; -static JoystickOpenedItem JoystickOpenList[16]; +static SDL_bool JoysticksAreGameControllers = SDL_FALSE; +static SDL12_Joystick *JoystickList = NULL; +static Uint32 NumJoysticks = 0; static Uint8 KeyState[SDLK12_LAST]; static SDL_bool MouseInputIsRelative = SDL_FALSE; static SDL_Point MousePosition = { 0, 0 }; @@ -1554,92 +1561,290 @@ SDL_Has3DNowExt(void) return (get_cpu_ext_features() & 0x40000000)? SDL_TRUE : SDL_FALSE; } -DECLSPEC SDL_Joystick * SDLCALL -SDL_JoystickOpen(int device_index) + +/* SDL 1.2 has no concept of joystick hotplug, so you only have + access to sticks seen during SDL_Init() and if one of them is + unplugged, all you can do is fail to open it, or stop reporting + new input. + + Also, we optionally let the app see SDL2 Game Controllers as + SDL 1.2 joysticks, which gives them a stable button/axis layout + and can deal with other hardware quirks. +*/ + +static SDL_bool +BogusJoystick(SDL12_Joystick *stick12) { - size_t i; - SDL20_LockJoysticks(); - for (i = 0; i < SDL_arraysize(JoystickOpenList); i++) { - if (JoystickOpenList[i].joystick == NULL) { - break; + const int device_index = (int) (stick12 - JoystickList); + if (!stick12 || (device_index < 0) || (device_index >= NumJoysticks)) { + SDL20_SetError("Invalid SDL_Joystick"); + return SDL_TRUE; + } + return SDL_FALSE; +} + +static SDL_bool +BogusJoystickIndex(const int device_index) +{ + if ((device_index < 0) || (device_index >= NumJoysticks)) { + SDL20_SetError("Invalid SDL_Joystick"); + return SDL_TRUE; + } + return SDL_FALSE; +} + +static int +FindJoystick12IndexByInstanceId(const SDL_JoystickID instance_id) +{ + int i; + for (i = 0; i < NumJoysticks; i++) { + if (JoystickList[i].instance_id == instance_id) { + return (SDL20_AtomicGet(&JoystickList[i].refcount) > 0) ? i : -1; } } + return -1; +} - if (i == SDL_arraysize(JoystickOpenList)) { - SDL20_UnlockJoysticks(); - SDL20_SetError("Too many open joysticks"); - return NULL; +static void +Init12Joystick(void) +{ + int numsticks20; + int i; + + JoysticksAreGameControllers = SDL12Compat_GetHintBoolean("SDL12COMPAT_USE_GAME_CONTROLLERS", SDL_FALSE); + NumJoysticks = 0; + + SDL20_LockJoysticks(); + + numsticks20 = SDL20_NumJoysticks(); + + if (numsticks20 > 255) { + numsticks20 = 255; /* it has to fit in a Uint8 for the joystick events. */ } - JoystickOpenList[i].joystick = SDL20_JoystickOpen(device_index); - if (JoystickOpenList[i].joystick) { - JoystickOpenList[i].device_index = device_index; + JoystickList = (SDL12_Joystick *) ((numsticks20 > 0) ? SDL20_calloc(numsticks20, sizeof (SDL12_Joystick)) : NULL); + if (JoystickList != NULL) { + for (i = 0; i < numsticks20; i++) { + const char *name; + SDL_bool opened; + + if (JoysticksAreGameControllers && !SDL20_IsGameController(i)) { + continue; + } + + name = JoysticksAreGameControllers ? SDL20_GameControllerNameForIndex(i) : SDL20_JoystickNameForIndex(i); + if (!name) { + name = JoysticksAreGameControllers ? "Generic SDL2 Game Controller" : "Generic SDL2 Joystick"; + } + + JoystickList[NumJoysticks].name = SDL20_strdup(name); + if (!JoystickList[NumJoysticks].name) { + continue; + } + + if (JoysticksAreGameControllers) { + JoystickList[NumJoysticks].dev.controller = SDL20_GameControllerOpen(i); + opened = JoystickList[NumJoysticks].dev.controller != NULL; + } else { + JoystickList[NumJoysticks].dev.joystick = SDL20_JoystickOpen(i); + opened = JoystickList[NumJoysticks].dev.joystick != NULL; + } + + if (!opened) { + SDL20_free(JoystickList[NumJoysticks].name); + JoystickList[NumJoysticks].name = NULL; + } + + JoystickList[NumJoysticks].instance_id = SDL20_JoystickGetDeviceInstanceID(i); + + NumJoysticks++; + } } SDL20_UnlockJoysticks(); - return JoystickOpenList[i].joystick; + + if ((NumJoysticks == 0) && (JoystickList)) { + SDL20_free(JoystickList); + JoystickList = NULL; + } else if (NumJoysticks < numsticks20) { /* shrink the array if possible. */ + void *ptr = SDL20_realloc(JoystickList, sizeof (*JoystickList) * NumJoysticks); + if (ptr) { + JoystickList = (SDL12_Joystick *) ptr; + } + } } -DECLSPEC void SDLCALL -SDL_JoystickClose(SDL_Joystick *joystick) +static void +Quit12Joystick(void) { - size_t i; - SDL20_LockJoysticks(); - for (i = 0; i < SDL_arraysize(JoystickOpenList); i++) { - if (JoystickOpenList[i].joystick == joystick) { - break; + int i; + for (i = 0; i < NumJoysticks; i++) { + SDL12_Joystick *stick12 = &JoystickList[i]; + if (JoysticksAreGameControllers) { + SDL20_GameControllerClose(stick12->dev.controller); + } else { + SDL20_JoystickClose(stick12->dev.joystick); } + SDL20_free(stick12->name); } - if (i < SDL_arraysize(JoystickOpenList)) { - JoystickOpenList[i].joystick = NULL; + SDL20_free(JoystickList); + JoystickList = NULL; + NumJoysticks = 0; +} + +DECLSPEC int SDLCALL +SDL_NumJoysticks(void) +{ + return NumJoysticks; +} + +DECLSPEC int SDLCALL +SDL_JoystickNumAxes(SDL12_Joystick *stick12) +{ + if (BogusJoystick(stick12)) { + return -1; } + return JoysticksAreGameControllers ? (SDL_CONTROLLER_AXIS_MAX + 1) : SDL20_JoystickNumAxes(stick12->dev.joystick); +} - SDL20_UnlockJoysticks(); +DECLSPEC int SDLCALL +SDL_JoystickNumBalls(SDL12_Joystick *stick12) +{ + if (BogusJoystick(stick12)) { + return -1; + } + return JoysticksAreGameControllers ? 0 : SDL20_JoystickNumBalls(stick12->dev.joystick); +} - SDL20_JoystickClose(joystick); +DECLSPEC int SDLCALL +SDL_JoystickNumHats(SDL12_Joystick *stick12) +{ + if (BogusJoystick(stick12)) { + return -1; + } + return JoysticksAreGameControllers ? 0 : SDL20_JoystickNumHats(stick12->dev.joystick); } -DECLSPEC const char * SDLCALL -SDL_JoystickName(int device_index) +DECLSPEC int SDLCALL +SDL_JoystickNumButtons(SDL12_Joystick *stick12) { - return SDL20_JoystickNameForIndex(device_index); + if (BogusJoystick(stick12)) { + return -1; + } + return JoysticksAreGameControllers ? (SDL_CONTROLLER_BUTTON_MAX + 1) : SDL20_JoystickNumButtons(stick12->dev.joystick); +} + +DECLSPEC void SDLCALL +SDL_JoystickUpdate(void) +{ + if (JoysticksAreGameControllers) { + SDL20_GameControllerUpdate(); + } else { + SDL20_JoystickUpdate(); + } } DECLSPEC int SDLCALL -SDL_JoystickIndex(SDL_Joystick *joystick) +SDL_JoystickEventState(int state) +{ + switch (state) { + case SDL_DISABLE: + case SDL_ENABLE: + if (JoysticksAreGameControllers) { + SDL20_JoystickEventState(state); + return SDL20_GameControllerEventState(state); + } + SDL20_GameControllerEventState(state); + return SDL20_JoystickEventState(state); + default: /* everything else is treated as SDL_QUERY */ + /* we turn joystick and controller event state off together, so we only have to query one. */ + return SDL20_JoystickEventState(SDL_QUERY); + } +} + +DECLSPEC Sint16 SDLCALL +SDL_JoystickGetAxis(SDL12_Joystick *stick12, int axis) { - size_t i; - SDL20_LockJoysticks(); - for (i = 0; i < SDL_arraysize(JoystickOpenList); i++) { - if (JoystickOpenList[i].joystick == joystick) { - break; - } + if (BogusJoystick(stick12)) { + return 0; } + return JoysticksAreGameControllers ? SDL20_GameControllerGetAxis(stick12->dev.controller, axis) : SDL20_JoystickGetAxis(stick12->dev.joystick, axis); +} - if (i < SDL_arraysize(JoystickOpenList)) { - SDL20_UnlockJoysticks(); - return JoystickOpenList[i].device_index; +DECLSPEC Uint8 SDLCALL +SDL_JoystickGetHat(SDL12_Joystick *stick12, int hat) +{ + if (BogusJoystick(stick12)) { + return 0; } + return JoysticksAreGameControllers ? 0 : SDL20_JoystickGetHat(stick12->dev.joystick, hat); +} - SDL20_UnlockJoysticks(); - return SDL20_SetError("Can't find joystick"); +DECLSPEC int SDLCALL +SDL_JoystickGetBall(SDL12_Joystick *stick12, int ball, int *dx, int *dy) +{ + if (BogusJoystick(stick12)) { + return 0; + } else if (JoysticksAreGameControllers) { + if (dx) { *dx = 0; } + if (dy) { *dy = 0; } + return SDL20_SetError("No joystick balls available"); + } + return SDL20_JoystickGetBall(stick12->dev.joystick, ball, dx, dy); +} + +DECLSPEC Uint8 SDLCALL +SDL_JoystickGetButton(SDL12_Joystick *stick12, int button) +{ + if (BogusJoystick(stick12)) { + return 0; + } + return JoysticksAreGameControllers ? SDL20_GameControllerGetButton(stick12->dev.controller, button) : SDL20_JoystickGetButton(stick12->dev.joystick, button); +} + +DECLSPEC SDL12_Joystick * SDLCALL +SDL_JoystickOpen(int device_index) +{ + if (BogusJoystickIndex(device_index)) { + return NULL; + } + + /* multiple opens just increments a refcount and returns the same object in SDL 1.2 Classic. */ + SDL20_AtomicAdd(&JoystickList[device_index].refcount, 1); + return &JoystickList[device_index]; +} + +DECLSPEC void SDLCALL +SDL_JoystickClose(SDL12_Joystick *stick12) +{ + if (!BogusJoystick(stick12)) { + /* we don't actually close anything here, just drop the refcount. */ + if (SDL20_AtomicAdd(&stick12->refcount, -1) == 0) { + SDL20_AtomicAdd(&stick12->refcount, 1); /* whoops, wasn't open, bounce it back to zero. */ + } + } +} + +DECLSPEC const char * SDLCALL +SDL_JoystickName(int device_index) +{ + return BogusJoystickIndex(device_index) ? NULL : JoystickList[device_index].name; +} + +DECLSPEC int SDLCALL +SDL_JoystickIndex(SDL12_Joystick *stick12) +{ + return BogusJoystick(stick12) ? -1 : (int) (stick12 - JoystickList); } DECLSPEC int SDLCALL SDL_JoystickOpened(int device_index) { - int retval = 0; - size_t i; - SDL20_LockJoysticks(); - for (i = 0; i < SDL_arraysize(JoystickOpenList); i++) { - if ((JoystickOpenList[i].joystick) && (JoystickOpenList[i].device_index == device_index)) { - retval = 1; - break; - } + if (BogusJoystickIndex(device_index)) { + return 0; /* SDL 1.2 classic doesn't return an error here, either. */ } - SDL20_UnlockJoysticks(); - return retval; + return SDL20_AtomicGet(&JoystickList[device_index].refcount) ? 1 : 0; } static SDL_PixelFormat * @@ -2071,6 +2276,10 @@ SDL_InitSubSystem(Uint32 sdl12flags) } #endif + if ((rc == 0) && (sdl20flags & SDL_INIT_JOYSTICK)) { + Init12Joystick(); /* if this fails, we just won't report any sticks. */ + } + return rc; } @@ -2130,6 +2339,7 @@ SDL_WasInit(Uint32 sdl12flags) return InitFlags20to12(SDL20_WasInit(sdl20flags)) | extraflags; } + static SDL12_Surface *EndVidModeCreate(void); static void Quit12Video(void) @@ -2188,6 +2398,10 @@ SDL_QuitSubSystem(Uint32 sdl12flags) EventThreadEnabled = SDL_FALSE; } + if (sdl12flags & SDL12_INIT_JOYSTICK) { + Quit12Joystick(); + } + SDL20_QuitSubSystem(sdl20flags); if ((SDL20_WasInit(0) == 0) && (!CDRomInit)) { @@ -4210,47 +4424,84 @@ EventFilter20to12(void *data, SDL_Event *event20) break; case SDL_JOYAXISMOTION: - event12.type = SDL12_JOYAXISMOTION; - event12.jaxis.which = (Uint8) event20->jaxis.which; - event12.jaxis.axis = event20->jaxis.axis; - event12.jaxis.value = event20->jaxis.value; + if (!JoysticksAreGameControllers) { + const int which = FindJoystick12IndexByInstanceId(event20->jaxis.which); + if (which != -1) { + event12.type = SDL12_JOYAXISMOTION; + event12.jaxis.which = (Uint8) which; + event12.jaxis.axis = event20->jaxis.axis; + event12.jaxis.value = event20->jaxis.value; + } + } break; case SDL_JOYBALLMOTION: - event12.type = SDL12_JOYBALLMOTION; - event12.jball.which = (Uint8) event20->jball.which; - event12.jball.ball = event20->jball.ball; - event12.jball.xrel = event20->jball.xrel; - event12.jball.yrel = event20->jball.yrel; + if (!JoysticksAreGameControllers) { + const int which = FindJoystick12IndexByInstanceId(event20->jball.which); + if (which != -1) { + event12.type = SDL12_JOYBALLMOTION; + event12.jball.which = (Uint8) which; + event12.jball.ball = event20->jball.ball; + event12.jball.xrel = event20->jball.xrel; + event12.jball.yrel = event20->jball.yrel; + } + } break; case SDL_JOYHATMOTION: - event12.type = SDL12_JOYHATMOTION; - event12.jhat.which = (Uint8) event20->jhat.which; - event12.jhat.hat = event20->jhat.hat; - event12.jhat.value = event20->jhat.value; + if (!JoysticksAreGameControllers) { + const int which = FindJoystick12IndexByInstanceId(event20->jhat.which); + if (which != -1) { + event12.type = SDL12_JOYHATMOTION; + event12.jhat.which = (Uint8) which; + event12.jhat.hat = event20->jhat.hat; + event12.jhat.value = event20->jhat.value; + } + } break; case SDL_JOYBUTTONDOWN: - event12.type = SDL12_JOYBUTTONDOWN; - event12.jbutton.which = (Uint8) event20->jbutton.which; - event12.jbutton.button = event20->jbutton.button; - event12.jbutton.state = event20->jbutton.state; + case SDL_JOYBUTTONUP: + if (!JoysticksAreGameControllers) { + const int which = FindJoystick12IndexByInstanceId(event20->jbutton.which); + if (which != -1) { + event12.type = (event20->jbutton.state) ? SDL12_JOYBUTTONDOWN : SDL12_JOYBUTTONUP; + event12.jbutton.which = (Uint8) which; + event12.jbutton.button = event20->jbutton.button; + event12.jbutton.state = event20->jbutton.state; + } + } break; - case SDL_JOYBUTTONUP: - event12.type = SDL12_JOYBUTTONUP; - event12.jbutton.which = (Uint8) event20->jbutton.which; - event12.jbutton.button = event20->jbutton.button; - event12.jbutton.state = event20->jbutton.state; + case SDL_CONTROLLERAXISMOTION: + if (JoysticksAreGameControllers) { + const int which = FindJoystick12IndexByInstanceId(event20->caxis.which); + if (which != -1) { + event12.type = SDL12_JOYAXISMOTION; + event12.jaxis.which = (Uint8) which; + event12.jaxis.axis = event20->caxis.axis; + event12.jaxis.value = event20->caxis.value; + } + } break; + case SDL_CONTROLLERBUTTONDOWN: + case SDL_CONTROLLERBUTTONUP: + if (JoysticksAreGameControllers) { + const int which = FindJoystick12IndexByInstanceId(event20->cbutton.which); + if (which != -1) { + event12.type = (event20->cbutton.state) ? SDL12_JOYBUTTONDOWN : SDL12_JOYBUTTONUP; + event12.jbutton.which = (Uint8) which; + event12.jbutton.button = event20->cbutton.button; + event12.jbutton.state = event20->cbutton.state; + } + } + break; + + /* case SDL_JOYDEVICEADDED: case SDL_JOYDEVICEREMOVED: - case SDL_CONTROLLERAXISMOTION: - case SDL_CONTROLLERBUTTONDOWN: - case SDL_CONTROLLERBUTTONUP: case SDL_CONTROLLERDEVICEADDED: case SDL_CONTROLLERDEVICEREMOVED: case SDL_CONTROLLERDEVICEREMAPPED: diff --git a/src/SDL20_include_wrapper.h b/src/SDL20_include_wrapper.h index 361a1fcfc..4d4be2220 100644 --- a/src/SDL20_include_wrapper.h +++ b/src/SDL20_include_wrapper.h @@ -83,7 +83,22 @@ #define SDL_WriteBE64 IGNORE_THIS_VERSION_OF_SDL_WriteBE64 #define SDL_GetThreadID IGNORE_THIS_VERSION_OF_SDL_GetThreadID #define SDL_ThreadID IGNORE_THIS_VERSION_OF_SDL_ThreadID +#define SDL_NumJoysticks IGNORE_THIS_VERSION_OF_SDL_NumJoysticks +#define SDL_JoystickNumAxes IGNORE_THIS_VERSION_OF_SDL_JoystickNumAxes +#define SDL_JoystickNumBalls IGNORE_THIS_VERSION_OF_SDL_JoystickNumBalls +#define SDL_JoystickNumHats IGNORE_THIS_VERSION_OF_SDL_JoystickNumHats +#define SDL_JoystickNumButtons IGNORE_THIS_VERSION_OF_SDL_JoystickNumButtons +#define SDL_JoystickUpdate IGNORE_THIS_VERSION_OF_SDL_JoystickUpdate +#define SDL_JoystickEventState IGNORE_THIS_VERSION_OF_SDL_JoystickEventState +#define SDL_JoystickGetAxis IGNORE_THIS_VERSION_OF_SDL_JoystickGetAxis +#define SDL_JoystickGetHat IGNORE_THIS_VERSION_OF_SDL_JoystickGetHat +#define SDL_JoystickGetBall IGNORE_THIS_VERSION_OF_SDL_JoystickGetBall +#define SDL_JoystickGetButton IGNORE_THIS_VERSION_OF_SDL_JoystickGetButton +#define SDL_JoystickOpen IGNORE_THIS_VERSION_OF_SDL_JoystickOpen +#define SDL_JoystickClose IGNORE_THIS_VERSION_OF_SDL_JoystickClose #define SDL_JoystickName IGNORE_THIS_VERSION_OF_SDL_JoystickName +#define SDL_JoystickIndex IGNORE_THIS_VERSION_OF_SDL_JoystickIndex +#define SDL_JoystickOpened IGNORE_THIS_VERSION_OF_SDL_JoystickOpened #define SDL_LoadBMP_RW IGNORE_THIS_VERSION_OF_SDL_LoadBMP_RW #define SDL_SaveBMP_RW IGNORE_THIS_VERSION_OF_SDL_SaveBMP_RW #define SDL_LoadWAV_RW IGNORE_THIS_VERSION_OF_SDL_LoadWAV_RW @@ -197,7 +212,22 @@ typedef void (__cdecl *pfnSDL_CurrentEndThread) (unsigned); #undef SDL_WriteBE64 #undef SDL_GetThreadID #undef SDL_ThreadID +#undef SDL_NumJoysticks +#undef SDL_JoystickNumAxes +#undef SDL_JoystickNumBalls +#undef SDL_JoystickNumHats +#undef SDL_JoystickNumButtons +#undef SDL_JoystickUpdate +#undef SDL_JoystickEventState +#undef SDL_JoystickGetAxis +#undef SDL_JoystickGetHat +#undef SDL_JoystickGetBall +#undef SDL_JoystickGetButton +#undef SDL_JoystickOpen +#undef SDL_JoystickClose #undef SDL_JoystickName +#undef SDL_JoystickIndex +#undef SDL_JoystickOpened #undef SDL_LoadBMP_RW #undef SDL_SaveBMP_RW #undef SDL_LoadWAV_RW @@ -215,6 +245,7 @@ typedef void (__cdecl *pfnSDL_CurrentEndThread) (unsigned); #undef SDL_RegisterApp #undef SDL_UnregisterApp + #ifdef SDL_mutexP #undef SDL_mutexP #endif diff --git a/src/SDL20_syms.h b/src/SDL20_syms.h index 92f22942e..84087ffc0 100644 --- a/src/SDL20_syms.h +++ b/src/SDL20_syms.h @@ -194,6 +194,7 @@ SDL20_SYM_PASSTHROUGH(int,CondWaitTimeout,(SDL_cond *a, SDL_mutex *b, Uint32 c), SDL20_SYM(int,AtomicGet,(SDL_atomic_t *a),(a),return) SDL20_SYM(void,AtomicSet,(SDL_atomic_t *a, int b),(a,b),) +SDL20_SYM(int,AtomicAdd,(SDL_atomic_t *a, int b),(a,b),return) SDL20_SYM(SDL_AudioSpec *,LoadWAV_RW,(SDL_RWops *a, int b, SDL_AudioSpec *c, Uint8 **d, Uint32 *e),(a,b,c,d,e),return) SDL20_SYM(int,OpenAudio,(SDL_AudioSpec *a, SDL_AudioSpec *b),(a,b),return) @@ -231,19 +232,29 @@ SDL20_SYM(SDL_bool,RemoveTimer,(SDL_TimerID a),(a),return) SDL20_SYM_PASSTHROUGH(Uint32,GetTicks,(void),(),return) SDL20_SYM_PASSTHROUGH(void,Delay,(Uint32 a),(a),) -SDL20_SYM_PASSTHROUGH(int,NumJoysticks,(void),(),return) +SDL20_SYM(SDL_bool,IsGameController,(int a),(a),return) +SDL20_SYM(const char *,GameControllerNameForIndex,(int a),(a),return) +SDL20_SYM(SDL_GameController *,GameControllerOpen,(int a),(a),return) +SDL20_SYM(void,GameControllerClose,(SDL_GameController *a),(a),) +SDL20_SYM(int,GameControllerEventState,(int a),(a),return) +SDL20_SYM(void,GameControllerUpdate,(void),(),) +SDL20_SYM(Sint16,GameControllerGetAxis,(SDL_GameController *a, SDL_GameControllerAxis b),(a,b),return) +SDL20_SYM(Uint8,GameControllerGetButton,(SDL_GameController *a, SDL_GameControllerButton b),(a,b),return) + +SDL20_SYM(int,NumJoysticks,(void),(),return) SDL20_SYM(const char *,JoystickNameForIndex,(int a),(a),return) +SDL20_SYM(SDL_JoystickID,JoystickGetDeviceInstanceID,(int a),(a),return) SDL20_SYM(SDL_Joystick *,JoystickOpen,(int a),(a),return) -SDL20_SYM_PASSTHROUGH(int,JoystickNumAxes,(SDL_Joystick *a),(a),return) -SDL20_SYM_PASSTHROUGH(int,JoystickNumBalls,(SDL_Joystick *a),(a),return) -SDL20_SYM_PASSTHROUGH(int,JoystickNumHats,(SDL_Joystick *a),(a),return) -SDL20_SYM_PASSTHROUGH(int,JoystickNumButtons,(SDL_Joystick *a),(a),return) -SDL20_SYM_PASSTHROUGH(void,JoystickUpdate,(void),(),) -SDL20_SYM_PASSTHROUGH(int,JoystickEventState,(int a),(a),return) -SDL20_SYM_PASSTHROUGH(Sint16,JoystickGetAxis,(SDL_Joystick *a, int b),(a,b),return) -SDL20_SYM_PASSTHROUGH(Uint8,JoystickGetHat,(SDL_Joystick *a, int b),(a,b),return) -SDL20_SYM_PASSTHROUGH(int,JoystickGetBall,(SDL_Joystick *a, int b, int *c, int *d),(a,b,c,d),return) -SDL20_SYM_PASSTHROUGH(Uint8,JoystickGetButton,(SDL_Joystick *a, int b),(a,b),return) +SDL20_SYM(int,JoystickNumAxes,(SDL_Joystick *a),(a),return) +SDL20_SYM(int,JoystickNumBalls,(SDL_Joystick *a),(a),return) +SDL20_SYM(int,JoystickNumHats,(SDL_Joystick *a),(a),return) +SDL20_SYM(int,JoystickNumButtons,(SDL_Joystick *a),(a),return) +SDL20_SYM(void,JoystickUpdate,(void),(),) +SDL20_SYM(int,JoystickEventState,(int a),(a),return) +SDL20_SYM(Sint16,JoystickGetAxis,(SDL_Joystick *a, int b),(a,b),return) +SDL20_SYM(Uint8,JoystickGetHat,(SDL_Joystick *a, int b),(a,b),return) +SDL20_SYM(int,JoystickGetBall,(SDL_Joystick *a, int b, int *c, int *d),(a,b,c,d),return) +SDL20_SYM(Uint8,JoystickGetButton,(SDL_Joystick *a, int b),(a,b),return) SDL20_SYM(void,JoystickClose,(SDL_Joystick *a),(a),return) SDL20_SYM(void,LockJoysticks,(void),(),) SDL20_SYM(void,UnlockJoysticks,(void),(),) From 3edd89f700d278b6c74b16a0f07c8b5de21869a6 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 18 Aug 2022 00:55:12 -0400 Subject: [PATCH 261/606] FIXME removal: Make sure VideoWindow20 isn't NULL before use. Reference Issue #143. --- src/SDL12_compat.c | 64 ++++++++++++++++++++++++++-------------------- 1 file changed, 36 insertions(+), 28 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index fc97c14e1..e31c5ef9a 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -931,8 +931,6 @@ typedef struct OpenGLEntryPoints #include "SDL20_syms.h" } OpenGLEntryPoints; - -/* !!! FIXME: grep for VideoWindow20 places that might care if it's NULL */ /* !!! FIXME: go through all of these. */ static Uint32 LinkedSDL2VersionInt = 0; static SDL_bool IsDummyVideo = SDL_FALSE; @@ -2702,7 +2700,7 @@ AdjustOpenGLLogicalScalingPoint(int *x, int *y) int adjusted_x, adjusted_y; /* Don't adjust anything if we're not using Logical Scaling */ - if (!OpenGLLogicalScalingFBO) { + if (!OpenGLLogicalScalingFBO || !VideoWindow20) { return; } @@ -2732,7 +2730,7 @@ AdjustOpenGLLogicalScalingVector(int *x, int *y, float *rx, float *ry) float trunc_x, trunc_y; /* Don't adjust anything if we're not using Logical Scaling */ - if (!OpenGLLogicalScalingFBO) { + if (!OpenGLLogicalScalingFBO || !VideoWindow20) { return; } @@ -4115,6 +4113,10 @@ EventFilter20to12(void *data, SDL_Event *event20) break; case SDL_WINDOWEVENT: + if (!VideoWindow20) { + break; /* no window? No event. */ + } + switch (event20->window.event) { /* don't send an SDL12_QUIT event for SDL_WINDOWEVENT_CLOSE; we only ever have a single window, so an SDL_QUIT will be @@ -4125,7 +4127,7 @@ EventFilter20to12(void *data, SDL_Event *event20) event12.type = SDL12_VIDEOEXPOSE; break; - case SDL_WINDOWEVENT_RESIZED: + case SDL_WINDOWEVENT_RESIZED: { /* don't generate a VIDEORESIZE event based on SIZE_CHANGED events: the recommended way to handle VIDEORESIZE is with a new SDL_SetVideoMode() call, and creating a new @@ -4135,20 +4137,16 @@ EventFilter20to12(void *data, SDL_Event *event20) /* don't report VIDEORESIZE if we're fullscreen-desktop; we're doing logical scaling and as far as the app is concerned the window doesn't change. */ - if (!VideoWindow20) { - FIXME("we should probably drop a lot of these events."); - break; /* there's no window? Drop this event. */ - } else { - const Uint32 flags = SDL20_GetWindowFlags(VideoWindow20); - if ((flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP) { - break; - } + const Uint32 flags = SDL20_GetWindowFlags(VideoWindow20); + if ((flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP) { + break; } event12.type = SDL12_VIDEORESIZE; event12.resize.w = event20->window.data1; event12.resize.h = event20->window.data2; break; + } case SDL_WINDOWEVENT_MINIMIZED: event12.type = SDL12_ACTIVEEVENT; @@ -5332,6 +5330,8 @@ InitializeOpenGLScaling(const int w, const int h) { int alpha_size = 0; + SDL_assert(VideoWindow20 != NULL); + /* Support the MOUSE_RELATIVE_SCALING hint from SDL 2.0 for OpenGL scaling. */ UseMouseRelativeScaling = SDL12Compat_GetHintBoolean("SDL_MOUSE_RELATIVE_SCALING", SDL_TRUE); @@ -6149,6 +6149,7 @@ GetDesiredMillisecondsPerFrame() { SDL_DisplayMode mode; if (VideoSurface12->flags & SDL12_FULLSCREEN) { + SDL_assert(VideoWindow20 != NULL); if (SDL20_GetWindowDisplayMode(VideoWindow20, &mode) == 0) { if (mode.refresh_rate) { return 1000 / mode.refresh_rate; @@ -6493,7 +6494,9 @@ SDL_WM_SetIcon(SDL12_Surface *icon12, Uint8 *mask) DECLSPEC int SDLCALL SDL_WM_IconifyWindow(void) { - SDL20_MinimizeWindow(VideoWindow20); + if (VideoWindow20) { + SDL20_MinimizeWindow(VideoWindow20); + } return 0; } @@ -6569,7 +6572,9 @@ HandleInputGrab(SDL12_GrabMode mode) const SDL_bool isfullscreen = (VideoSurface12 && (VideoSurface12->flags & SDL12_FULLSCREEN)) ? SDL_TRUE : SDL_FALSE; const SDL_bool wantgrab = (isfullscreen || (mode == SDL12_GRAB_ON)) ? SDL_TRUE : SDL_FALSE; if (VideoWindowGrabbed != wantgrab) { - SDL20_SetWindowGrab(VideoWindow20, wantgrab); + if (VideoWindow20) { + SDL20_SetWindowGrab(VideoWindow20, wantgrab); + } VideoWindowGrabbed = wantgrab; UpdateRelativeMouseMode(); } @@ -6591,7 +6596,9 @@ SDL_WarpMouse(Uint16 x, Uint16 y) MousePosition.x = (int) x; MousePosition.y = (int) y; } else { - SDL20_WarpMouseInWindow(VideoWindow20, x, y); + if (VideoWindow20) { + SDL20_WarpMouseInWindow(VideoWindow20, x, y); + } } } @@ -6599,17 +6606,17 @@ DECLSPEC Uint8 SDLCALL SDL_GetAppState(void) { Uint8 state12 = 0; - Uint32 flags20 = 0; - - flags20 = SDL20_GetWindowFlags(VideoWindow20); - if ((flags20 & SDL_WINDOW_SHOWN) && !(flags20 & SDL_WINDOW_MINIMIZED)) { - state12 |= SDL12_APPACTIVE; - } - if (flags20 & SDL_WINDOW_INPUT_FOCUS) { - state12 |= SDL12_APPINPUTFOCUS; - } - if (flags20 & SDL_WINDOW_MOUSE_FOCUS) { - state12 |= SDL12_APPMOUSEFOCUS; + if (VideoWindow20) { + const Uint32 flags20 = SDL20_GetWindowFlags(VideoWindow20); + if ((flags20 & SDL_WINDOW_SHOWN) && !(flags20 & SDL_WINDOW_MINIMIZED)) { + state12 |= SDL12_APPACTIVE; + } + if (flags20 & SDL_WINDOW_INPUT_FOCUS) { + state12 |= SDL12_APPINPUTFOCUS; + } + if (flags20 & SDL_WINDOW_MOUSE_FOCUS) { + state12 |= SDL12_APPMOUSEFOCUS; + } } return state12; } @@ -7267,6 +7274,7 @@ SDL_SetGamma(float red, float green, float blue) } else { SDL20_CalculateGammaRamp(blue, blue_ramp); } + return SDL20_SetWindowGammaRamp(VideoWindow20, red_ramp, green_ramp, blue_ramp); } @@ -8781,7 +8789,7 @@ SDL_GL_DisableContext(void) DECLSPEC void SDLCALL SDL_GL_EnableContext_Thread(void) { - const SDL_bool enable = (VideoGLContext20 && VideoWindow20)? SDL_TRUE : SDL_FALSE; + const SDL_bool enable = (VideoGLContext20 && VideoWindow20) ? SDL_TRUE : SDL_FALSE; SDL20_GL_MakeCurrent(enable ? VideoWindow20 : NULL, enable ? VideoGLContext20 : NULL); } From a219db64b584d6b8be97f26b14cbcc9c51ae2d60 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 18 Aug 2022 09:46:49 -0400 Subject: [PATCH 262/606] FIXME removal: Wrap event processing in a mutex. Reference Issue #143. --- src/SDL12_compat.c | 129 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 109 insertions(+), 20 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index e31c5ef9a..108ab9b9c 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1005,7 +1005,6 @@ static GLuint OpenGLCurrentReadFBO = 0; static GLuint OpenGLCurrentDrawFBO = 0; static SDL_bool ForceGLSwapBufferContext = SDL_FALSE; -/* !!! FIXME: need a mutex for the event queue. */ #define SDL12_MAXEVENTS 128 typedef struct EventQueueType { @@ -1014,6 +1013,7 @@ typedef struct EventQueueType struct EventQueueType *next; } EventQueueType; +static SDL_mutex *EventQueueMutex = NULL; static EventQueueType EventQueuePool[SDL12_MAXEVENTS]; static EventQueueType *EventQueueHead = NULL; static EventQueueType *EventQueueTail = NULL; @@ -2143,8 +2143,14 @@ Init12Video(void) IsDummyVideo = ((driver != NULL) && (SDL20_strcmp(driver, "dummy") == 0)) ? SDL_TRUE : SDL_FALSE; - for (i = 0; i < SDL12_MAXEVENTS-1; i++) + EventQueueMutex = SDL20_CreateMutex(); + if (EventQueueMutex == NULL) { + return -1; + } + + for (i = 0; i < SDL12_MAXEVENTS-1; i++) { EventQueuePool[i].next = &EventQueuePool[i+1]; + } EventQueuePool[SDL12_MAXEVENTS-1].next = NULL; EventQueueHead = EventQueueTail = NULL; @@ -2365,6 +2371,11 @@ Quit12Video(void) SDL_FreeCursor(CurrentCursor12); VideoModes = NULL; VideoModesCount = 0; + + if (EventQueueMutex) { + SDL20_DestroyMutex(EventQueueMutex); + EventQueueMutex = NULL; + } } DECLSPEC void SDLCALL @@ -2481,8 +2492,9 @@ SDL_VideoDriverName(char *namebuf, int maxlen) } -DECLSPEC int SDLCALL -SDL_PollEvent(SDL12_Event *event12) +/* you MUST hold EventQueueMutex before calling this! */ +static int +SDL_PollEvent_locked(SDL12_Event *event12) { EventQueueType *next; @@ -2507,7 +2519,24 @@ SDL_PollEvent(SDL12_Event *event12) } DECLSPEC int SDLCALL -SDL_PushEvent(SDL12_Event *event12) +SDL_PollEvent(SDL12_Event *event12) +{ + int retval; + + if (!EventQueueMutex) { + return 0; + } + + SDL20_LockMutex(EventQueueMutex); + retval = SDL_PollEvent_locked(event12); + SDL20_UnlockMutex(EventQueueMutex); + + return retval; +} + +/* you MUST hold EventQueueMutex before calling this! */ +static int +SDL_PushEvent_locked(SDL12_Event *event12) { EventQueueType *item = EventQueueAvailable; if (item == NULL) { @@ -2534,7 +2563,25 @@ SDL_PushEvent(SDL12_Event *event12) } DECLSPEC int SDLCALL -SDL_PeepEvents(SDL12_Event *events12, int numevents, SDL_eventaction action, Uint32 mask) +SDL_PushEvent(SDL12_Event *event12) +{ + int retval; + + if (!EventQueueMutex) { + return SDL20_SetError("SDL not initialized"); + } + + SDL20_LockMutex(EventQueueMutex); + retval = SDL_PushEvent_locked(event12); + SDL20_UnlockMutex(EventQueueMutex); + + return retval; +} + + +/* you MUST hold EventQueueMutex before calling this! */ +static int +SDL_PeepEvents_locked(SDL12_Event *events12, int numevents, SDL_eventaction action, Uint32 mask) { SDL12_Event dummy_event; @@ -2608,46 +2655,78 @@ SDL_PeepEvents(SDL12_Event *events12, int numevents, SDL_eventaction action, Uin return 0; } +DECLSPEC int SDLCALL +SDL_PeepEvents(SDL12_Event *events12, int numevents, SDL_eventaction action, Uint32 mask) +{ + int retval; + + if (!EventQueueMutex) { + return SDL20_SetError("SDL not initialized"); + } + + SDL20_LockMutex(EventQueueMutex); + retval = SDL_PeepEvents_locked(events12, numevents, action, mask); + SDL20_UnlockMutex(EventQueueMutex); + + return retval; +} + DECLSPEC int SDLCALL SDL_WaitEvent(SDL12_Event *event12) { - FIXME("In 1.2, this only fails (-1) if you haven't SDL_Init()'d."); + if (!EventQueueMutex) { + return SDL20_SetError("SDL not initialized"); + } + + /* the 1.2 entry point for PollEvent will grab/release the EventQueueMutex */ while (!SDL_PollEvent(event12)) { SDL20_Delay(10); } + return 1; } static SDL_bool PushEventIfNotFiltered(SDL12_Event *event12) { + SDL_bool retval = SDL_FALSE; if (event12->type != SDL12_NOEVENT) { + SDL_assert(EventQueueMutex != NULL); + SDL20_LockMutex(EventQueueMutex); if (EventStates[event12->type] != SDL_IGNORE) { if ((!EventFilter12) || (EventFilter12(event12))) { - return (SDL_PushEvent(event12) == 0)? SDL_TRUE : SDL_FALSE; + retval = (SDL_PushEvent(event12) == 0)? SDL_TRUE : SDL_FALSE; } } + SDL20_UnlockMutex(EventQueueMutex); } - return SDL_FALSE; + return retval; } DECLSPEC Uint8 SDLCALL SDL_EventState(Uint8 type, int state) { + Uint8 retval = 0; /* the values of "state" match between 1.2 and 2.0 */ - const Uint8 retval = EventStates[type]; - SDL12_Event e; + if (EventQueueMutex) { + SDL12_Event e; - if (state != SDL_QUERY) { - EventStates[type] = state; - if ((type == SDL12_SYSWMEVENT) && SupportSysWM) { /* we only enable syswm in SDL2 if it makes sense. */ - SDL20_EventState(SDL_SYSWMEVENT, state); + SDL20_LockMutex(EventQueueMutex); + + retval = EventStates[type]; + if (state != SDL_QUERY) { + EventStates[type] = state; + if ((type == SDL12_SYSWMEVENT) && SupportSysWM) { /* we only enable syswm in SDL2 if it makes sense. */ + SDL20_EventState(SDL_SYSWMEVENT, state); + } } - } - if (state == SDL_IGNORE) { /* drop existing events of this type. */ - while (SDL_PeepEvents(&e, 1, SDL_GETEVENT, (1< Date: Thu, 18 Aug 2022 16:07:03 -0400 Subject: [PATCH 263/606] SDL_GetVideoInfo: Attempt to correctly set wm_available. This is an inexact science, but it's not like new window-based desktop user interfaces pop up every day, so it's better than the old code which just said everything had a window manager. --- src/SDL12_compat.c | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 108ab9b9c..5a523191b 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -2131,6 +2131,41 @@ Init12VidModes(void) #include "default_cursor.h" DECLSPEC void SDLCALL SDL_FreeCursor(SDL12_Cursor *); +static int +HasWmAvailable(const char *driver) +{ + /* This is not perfect, but this emcompasses everything that SDL 2.22.0 + offers. Most things are console or framebuffer targets, so it's + easier to list things that are actual GUI user interfaces here. */ + static const char * const gui_targets[] = { + #ifdef _WIN32 + "windows", "winrt", + #endif + #ifdef __APPLE__ + "cocoa", + #endif + #ifdef __OS2__ + "DIVE", "VMAN", + #endif + #ifdef __HAIKU__ + "haiku", + #endif + #ifdef __QNX__ + "qnx", /* I _think_ this has a window manager... */ + #endif + "x11", "wayland" /* just assume anything can MAYBE have these, even if they wouldn't. */ + }; + int i; + + for (i = 0; i < SDL_arraysize(gui_targets); i++) { + if (SDL20_strcasecmp(driver, gui_targets[i]) == 0) { + return 1; + } + } + + return 0; +} + static int Init12Video(void) { @@ -2192,7 +2227,7 @@ Init12Video(void) VideoInfo12.vfmt = PixelFormat20to12(&VideoInfoVfmt12, &VideoInfoPalette12, VideoInfoVfmt20); VideoInfo12.current_w = mode.w; VideoInfo12.current_h = mode.h; - VideoInfo12.wm_available = 1; /* FIXME ? */ + VideoInfo12.wm_available = HasWmAvailable(driver); VideoInfo12.video_mem = 1024 * 256; /* good enough. */ } From d71318ae57e461e09f73c97825445997458ed775 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 18 Aug 2022 16:48:02 -0400 Subject: [PATCH 264/606] Logical GL scaling: Only use depth/stencil renderbuffers if requested. --- src/SDL12_compat.c | 37 ++++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 5a523191b..91029c91e 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -5443,6 +5443,8 @@ static SDL_bool InitializeOpenGLScaling(const int w, const int h) { int alpha_size = 0; + int depth_size = 0; + int stencil_size = 0; SDL_assert(VideoWindow20 != NULL); @@ -5457,8 +5459,9 @@ InitializeOpenGLScaling(const int w, const int h) OpenGLFuncs.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); SDL20_GL_SwapWindow(VideoWindow20); - FIXME("This should check if app requested a depth buffer, etc, too."); SDL20_GL_GetAttribute(SDL_GL_ALPHA_SIZE, &alpha_size); + SDL20_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &depth_size); + SDL20_GL_GetAttribute(SDL_GL_STENCIL_SIZE, &stencil_size); if (!OpenGLLogicalScalingFBO) { OpenGLFuncs.glGenFramebuffers(1, &OpenGLLogicalScalingFBO); @@ -5476,10 +5479,18 @@ InitializeOpenGLScaling(const int w, const int h) OpenGLFuncs.glBindRenderbuffer(GL_RENDERBUFFER, OpenGLLogicalScalingColor); OpenGLFuncs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, OpenGLLogicalScalingSamples, (alpha_size > 0) ? GL_RGBA8 : GL_RGB8, w, h); OpenGLFuncs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, OpenGLLogicalScalingColor); - OpenGLFuncs.glBindRenderbuffer(GL_RENDERBUFFER, OpenGLLogicalScalingDepth); - OpenGLFuncs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, OpenGLLogicalScalingSamples, GL_DEPTH24_STENCIL8, w, h); - OpenGLFuncs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, OpenGLLogicalScalingDepth); - OpenGLFuncs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, OpenGLLogicalScalingDepth); + + if (depth_size || stencil_size) { + OpenGLFuncs.glBindRenderbuffer(GL_RENDERBUFFER, OpenGLLogicalScalingDepth); + OpenGLFuncs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, OpenGLLogicalScalingSamples, GL_DEPTH24_STENCIL8, w, h); + if (depth_size) { + OpenGLFuncs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, OpenGLLogicalScalingDepth); + } + if (stencil_size) { + OpenGLFuncs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, OpenGLLogicalScalingDepth); + } + } + OpenGLFuncs.glBindRenderbuffer(GL_RENDERBUFFER, 0); if ((OpenGLFuncs.glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) || OpenGLFuncs.glGetError()) { @@ -5506,10 +5517,18 @@ InitializeOpenGLScaling(const int w, const int h) OpenGLFuncs.glBindRenderbuffer(GL_RENDERBUFFER, OpenGLLogicalScalingMultisampleColor); OpenGLFuncs.glRenderbufferStorage(GL_RENDERBUFFER, (alpha_size > 0) ? GL_RGBA8 : GL_RGB8, w, h); OpenGLFuncs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, OpenGLLogicalScalingMultisampleColor); - OpenGLFuncs.glBindRenderbuffer(GL_RENDERBUFFER, OpenGLLogicalScalingMultisampleDepth); - OpenGLFuncs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, w, h); - OpenGLFuncs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, OpenGLLogicalScalingMultisampleDepth); - OpenGLFuncs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, OpenGLLogicalScalingMultisampleDepth); + + if (depth_size || stencil_size) { + OpenGLFuncs.glBindRenderbuffer(GL_RENDERBUFFER, OpenGLLogicalScalingMultisampleDepth); + OpenGLFuncs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, w, h); + if (depth_size) { + OpenGLFuncs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, OpenGLLogicalScalingMultisampleDepth); + } + if (stencil_size) { + OpenGLFuncs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, OpenGLLogicalScalingMultisampleDepth); + } + } + OpenGLFuncs.glBindRenderbuffer(GL_RENDERBUFFER, 0); if ((OpenGLFuncs.glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) || OpenGLFuncs.glGetError()) { From 3d3401858a11caf2c4203935144897ef0d08e1ed Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 18 Aug 2022 16:54:21 -0400 Subject: [PATCH 265/606] FIXME removal: take out notes about bgr vs rgb. This was wondering if using BGR pixel layout would be more correct/efficient, but honestly it's not hurting anything as it is now, so I'm just deleting the FIXMEs. Reference Issue #143. --- src/SDL12_compat.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 91029c91e..6948e8d4f 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -5639,9 +5639,9 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12) #endif switch (bpp) { case 8: appfmt = SDL_PIXELFORMAT_INDEX8; break; - case 16: appfmt = SDL_PIXELFORMAT_RGB565; FIXME("bgr instead of rgb?"); break; - case 24: appfmt = SDL_PIXELFORMAT_RGB888; FIXME("bgr instead of rgb?"); break; - case 32: appfmt = SDL_PIXELFORMAT_XRGB8888; FIXME("bgr instead of rgb?"); break; + case 16: appfmt = SDL_PIXELFORMAT_RGB565; break; + case 24: appfmt = SDL_PIXELFORMAT_RGB888; break; + case 32: appfmt = SDL_PIXELFORMAT_XRGB8888; break; default: SDL20_SetError("Unsupported bits-per-pixel"); return NULL; } @@ -6222,7 +6222,7 @@ SDL_DisplayFormatAlpha(SDL12_Surface *surface12) } /* we only allow a few formats for the screen surface, and this is the appropriate alpha format for all of them. */ - fmt20 = SDL20_AllocFormat(SDL_PIXELFORMAT_ARGB8888); FIXME("bgr instead of rgb?"); + fmt20 = SDL20_AllocFormat(SDL_PIXELFORMAT_ARGB8888); if (!fmt20) { return NULL; } From 90a33cda31b3a76b99e3cf29c0291f79e2453cd5 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 18 Aug 2022 22:14:09 -0400 Subject: [PATCH 266/606] FIXME removal: this _could_ be SIMD'd, but...it's probably not worth it. Reference Issue #143. --- src/SDL12_compat.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 6948e8d4f..97b6302ff 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -5989,9 +5989,6 @@ SaveDestAlpha(SDL12_Surface *src12, SDL12_Surface *dst12, Uint8 **retval) } dptr = dstalpha; - if ((amask == 0xFF) || (amask == 0xFF00) || (amask == 0xFF0000) ||(amask == 0xFF000000)) { - FIXME("this could be SIMD'd"); - } if (dst12->format->BytesPerPixel == 2) { const Uint16 *sptr = (const Uint16 *) dst12->pixels; for (y = 0; y < h; y++) { @@ -6030,9 +6027,6 @@ RestoreDestAlpha(SDL12_Surface *dst12, Uint8 *dstalpha) const Uint32 ashift = dst12->format->Ashift; const Uint16 pitch = dst12->pitch; - if ((amask == 0xFF) || (amask == 0xFF00) || (amask == 0xFF0000) ||(amask == 0xFF000000)) { - FIXME("this could be SIMD'd"); - } if (dst12->format->BytesPerPixel == 2) { Uint16 *dptr = (Uint16 *) dst12->pixels; for (y = 0; y < h; y++) { From a97def0d98a2542113b1b66f8c536efbc6b6bbfb Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 19 Aug 2022 09:41:57 -0400 Subject: [PATCH 267/606] audio: Clean up if there's a stream reset failure in SDL_OpenAudio. Reference Issue #143. --- src/SDL12_compat.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 97b6302ff..c5c539ee3 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -7980,7 +7980,7 @@ mp3_sdlrwops_seek(void *data, int offset, drmp3_seek_origin origin) static int OpenSDL2AudioDevice(SDL_AudioSpec *); -static void CloseSDL2AudioDevice(void); +static int CloseSDL2AudioDevice(void); static SDL_bool ResetAudioStream(SDL_AudioStream **_stream, SDL_AudioSpec *spec, const SDL_AudioSpec *to, const SDL_AudioFormat fromfmt, const Uint8 fromchannels, const int fromfreq); typedef struct @@ -8737,13 +8737,13 @@ OpenSDL2AudioDevice(SDL_AudioSpec *want) return retval; } -static void +static int CloseSDL2AudioDevice(void) { - int close_sdl2_device; + SDL_bool close_sdl2_device; SDL20_LockAudio(); - close_sdl2_device = (audio_cbdata && !audio_cbdata->app_callback_opened && !audio_cbdata->cdrom_opened); + close_sdl2_device = (audio_cbdata && !audio_cbdata->app_callback_opened && !audio_cbdata->cdrom_opened) ? SDL_TRUE : SDL_FALSE; SDL20_UnlockAudio(); if (close_sdl2_device) { @@ -8754,13 +8754,15 @@ CloseSDL2AudioDevice(void) SDL20_free(audio_cbdata); audio_cbdata = NULL; } + + return -1; } DECLSPEC int SDLCALL SDL_OpenAudio(SDL_AudioSpec *want, SDL_AudioSpec *obtained) { - int already_opened; + SDL_bool already_opened; /* SDL2 uses a NULL callback to mean "we plan to use SDL_QueueAudio()" */ if (want && (want->callback == NULL)) { @@ -8768,7 +8770,7 @@ SDL_OpenAudio(SDL_AudioSpec *want, SDL_AudioSpec *obtained) } SDL20_LockAudio(); - already_opened = audio_cbdata && audio_cbdata->app_callback_opened; + already_opened = (audio_cbdata && audio_cbdata->app_callback_opened) ? SDL_TRUE : SDL_FALSE; SDL20_UnlockAudio(); if (already_opened) { return SDL20_SetError("Audio device already opened"); @@ -8807,17 +8809,16 @@ SDL_OpenAudio(SDL_AudioSpec *want, SDL_AudioSpec *obtained) } SDL20_memcpy(&audio_cbdata->app_callback_format, want, sizeof (SDL_AudioSpec)); - audio_cbdata->app_callback_opened = SDL_TRUE; SDL20_AtomicSet(&audio_callback_paused, SDL_TRUE); /* app callback always starts paused after open. */ - FIXME("Cleanup from failures in here"); SDL_assert(audio_cbdata->app_callback_stream == NULL); - if (!ResetAudioStream(&audio_cbdata->app_callback_stream, &audio_cbdata->app_callback_format, &audio_cbdata->device_format, want->format, want->channels, want->freq)) { - FIXME("Close audio device if nothing else was using it"); - return -1; + SDL20_UnlockAudio(); /* make sure CD audio doesn't hang if it's playing. */ + return CloseSDL2AudioDevice(); /* will stay open if CD audio is still playing, cleans up otherwise. */ } + audio_cbdata->app_callback_opened = SDL_TRUE; + SDL20_UnlockAudio(); /* we're off and going. */ return 0; From 5dae287f9ff684abd0568b326812cddde9dd352c Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 19 Aug 2022 10:22:50 -0400 Subject: [PATCH 268/606] FIXME removal: "go through all of these" I think this was probably just a "see if these all need to be global variables" or "do we still use all of these?" or something...but I think it's okay. Reference Issue #143. --- src/SDL12_compat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index c5c539ee3..4ee9aa6dd 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -931,7 +931,7 @@ typedef struct OpenGLEntryPoints #include "SDL20_syms.h" } OpenGLEntryPoints; -/* !!! FIXME: go through all of these. */ + static Uint32 LinkedSDL2VersionInt = 0; static SDL_bool IsDummyVideo = SDL_FALSE; static VideoModeList *VideoModes = NULL; From 2aa92dbb0e243fbab55b6c4f901861f76337b56d Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 19 Aug 2022 10:30:23 -0400 Subject: [PATCH 269/606] FIXME removal: No plans to implement the SDL 1.2 parachute. Reference Issue #143. --- src/SDL12_compat.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 4ee9aa6dd..c618cc2af 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -2285,6 +2285,15 @@ SDL_InitSubSystem(Uint32 sdl12flags) SDL20_setenv("SDL_VIDEODRIVER", forcevideodrv, 1); } + /* note that currently we ignore SDL12_INIT_NOPARACHUTE, since + there _isn't_ a parachute in SDL2, and mostly it was meant to deal + with X11's XVidMode leaving the display resolution busted if the app + didn't call SDL_Quit() before leaving...but most sdl12-compat cases + (except OpenGL rendering without logical scaling) use + FULLSCREEN_DESKTOP for fullscreen modes, and modern X11 doesn't + have this problem, so we're ignoring the parachute until a reasonable + need arises. */ + #define SETFLAG(flag) if (sdl12flags & SDL12_INIT_##flag) sdl20flags |= SDL_INIT_##flag SETFLAG(TIMER); SETFLAG(AUDIO); @@ -2325,7 +2334,6 @@ SDL_InitSubSystem(Uint32 sdl12flags) DECLSPEC int SDLCALL SDL_Init(Uint32 sdl12flags) { - FIXME("there is never a parachute in SDL2, should we catch segfaults ourselves?"); return SDL_InitSubSystem(sdl12flags); /* there's no difference betwee Init and InitSubSystem in SDL2. */ } From 5e74b4b9ae8586a359b24df9f61398f2d6c69f4d Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 19 Aug 2022 10:49:32 -0400 Subject: [PATCH 270/606] audio: Support the SDL_AUDIO_[FORMAT|FREQUENCY|CHANNELS|SAMPLES] env vars. Reference Issue #143. --- src/SDL12_compat.c | 54 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 46 insertions(+), 8 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index c618cc2af..6364b1a66 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -8784,22 +8784,60 @@ SDL_OpenAudio(SDL_AudioSpec *want, SDL_AudioSpec *obtained) return SDL20_SetError("Audio device already opened"); } - FIXME("Respect 1.2 environment variables for defining format here."); if (!want->format) { - want->format = AUDIO_S16SYS; + const char *env = SDL20_getenv("SDL_AUDIO_FORMAT"); /* SDL 1.2 checks this. */ + if (env != NULL) { + if (0) {} + else if (SDL20_strcmp(env, "U8") == 0) { want->format = AUDIO_U8; } + else if (SDL20_strcmp(env, "S8") == 0) { want->format = AUDIO_S8; } + else if (SDL20_strcmp(env, "U16") == 0) { want->format = AUDIO_U16SYS; } + else if (SDL20_strcmp(env, "S16") == 0) { want->format = AUDIO_S16SYS; } + else if (SDL20_strcmp(env, "U16LSB") == 0) { want->format = AUDIO_U16LSB; } + else if (SDL20_strcmp(env, "S16LSB") == 0) { want->format = AUDIO_S16LSB; } + else if (SDL20_strcmp(env, "U16MSB") == 0) { want->format = AUDIO_U16MSB; } + else if (SDL20_strcmp(env, "S16MSB") == 0) { want->format = AUDIO_S16MSB; } + else if (SDL20_strcmp(env, "U16SYS") == 0) { want->format = AUDIO_U16SYS; } + else if (SDL20_strcmp(env, "S16SYS") == 0) { want->format = AUDIO_S16SYS; } + } + if (!want->format) { + want->format = AUDIO_S16SYS; + } } + if (!want->freq) { - want->freq = 22050; + const char *env = SDL20_getenv("SDL_AUDIO_FREQUENCY"); /* SDL 1.2 checks this. */ + if (env != NULL) { + want->freq = SDL20_atoi(env); + } + if (!want->freq) { + want->freq = 22050; + } want->samples = 0; } + if (!want->channels) { - want->channels = 2; + const char *env = SDL20_getenv("SDL_AUDIO_CHANNELS"); /* SDL 1.2 checks this. */ + if (env != NULL) { + want->channels = SDL20_atoi(env); + } + if (!want->channels) { + want->channels = 2; + } } + if (!want->samples) { - Uint32 samp = (want->freq / 1000) * 46; /* ~46 ms */ - Uint32 pow2 = 1; - while (pow2 < samp) pow2 <<= 1; - want->samples = pow2; + const char *env = SDL20_getenv("SDL_AUDIO_SAMPLES"); /* SDL 1.2 checks this. */ + if (env != NULL) { + want->samples = SDL20_atoi(env); + } + if (!want->samples) { + const Uint32 samp = (want->freq / 1000) * 46; /* ~46 ms */ + Uint32 pow2 = 1; + while (pow2 < samp) { + pow2 <<= 1; + } + want->samples = pow2; + } } /* the app always passes callback data through an SDL_AudioStream, since it From a53cf6238e9c664035d0db63ff85c31e45326c1e Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 19 Aug 2022 10:52:56 -0400 Subject: [PATCH 271/606] FIXME removal: We're not going to export glBindFramebuffer ourselves. Reference Issue #143. --- src/SDL12_compat.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 6364b1a66..5017f2e47 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -5578,17 +5578,19 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12) FIXME("Should we offer scaling for windowed modes, too?"); if (flags12 & SDL12_OPENGL) { - /* !!! FIXME: the reason we have a toggle to prevent this is because an app might use + /* For now we default GL scaling to ENABLED. If an app breaks or is linked directly + to glBindFramebuffer, they'll need to turn it off with this environment variable. + + The reason we have a toggle to prevent this is because an app might use FBOs directly, and will cause this to break if they bind Framebuffer 0 instead of our render target. If we can fool them into calling a fake glBindFramebuffer that binds our logical FBO instead of the window framebuffer, we can probably work with these apps, too. That's easy from SDL_GL_GetProcAddress, but we - maybe need to export the symbol from here too, for those that link against - OpenGL directly. UT2004 is known to use FBOs with SDL 1.2, and I assume - idTech 4 games (Doom 3, Quake 4, Prey) do as well. */ + would need to export the symbol from here too, for those that link against + OpenGL directly, and we don't want to risk that. - /* for now we default GL scaling to ENABLED. If an app breaks or is linked directly - to glBindFramebuffer, they'll need to turn it off with this environment variable */ + UT2004 is known to use FBOs with SDL 1.2, and I assume idTech 4 games (Doom 3, + Quake 4, Prey) do as well. */ use_gl_scaling = SDL12Compat_GetHintBoolean("SDL12COMPAT_OPENGL_SCALING", SDL_TRUE); /* default use_highdpi to false for OpenGL windows when not using From 2273b30aea8de47b6fe18756d3537bbb969ad429 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 19 Aug 2022 11:00:55 -0400 Subject: [PATCH 272/606] FIXME removal: neither of these FIXMEs match what SDL 1.2 did. Reference Issue #143. --- src/SDL12_compat.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 5017f2e47..f539e6039 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -5657,9 +5657,6 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12) SDL_assert((VideoSurface12 != NULL) == (VideoWindow20 != NULL)); - FIXME("don't do anything if the window's dimensions, etc haven't changed."); - FIXME("we need to preserve VideoSurface12 (but not its pixels), I think..."); - if (VideoSurface12 && ((VideoSurface12->flags & SDL12_OPENGL) != (flags12 & SDL12_OPENGL))) { EndVidModeCreate(); /* rebuild the window if moving to/from a GL context */ } else if (VideoSurface12 && (VideoSurface12->surface20->format->format != appfmt)) { From ffd1c00d9d19577c5b8723787e9ee18eceac8152 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 19 Aug 2022 15:15:35 -0400 Subject: [PATCH 273/606] video: Support SDL_ANYFORMAT. Reference Issue #143. --- src/SDL12_compat.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index f539e6039..9a90bf651 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -5621,8 +5621,6 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12) } } - FIXME("handle SDL_ANYFORMAT"); - if ((width < 0) || (height < 0)) { SDL20_SetError("Invalid width or height"); return NULL; @@ -5641,9 +5639,19 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12) } if (bpp == 0) { + flags12 |= SDL12_ANYFORMAT; bpp = SDL_BITSPERPIXEL(dmode.format); } + if ((bpp != 8) && (bpp != 16) && (bpp != 24) && (bpp != 32)) { + if (flags12 & SDL12_ANYFORMAT) { + bpp = 32; + } else { + SDL20_SetError("Unsupported bits-per-pixel"); + return NULL; + } + } + #if !SDL_VERSION_ATLEAST(2,0,14) #define SDL_PIXELFORMAT_XRGB8888 SDL_PIXELFORMAT_RGB888 #endif From d9708833642f1df2ee665f97054ebdab6b775f32 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 19 Aug 2022 16:35:07 -0400 Subject: [PATCH 274/606] FIXME removal: We _could_ request a simpler GL context, but don't. It's risky to find out we broke something this way when nothing is actually having a problem at the moment, we'd have to juggle the state between what SDL 1.2 is pretending for the app and what SDL2 actually used, and we're not talking about _that_ large a resource savings anyhow. Reference Issue #143. --- src/SDL12_compat.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 9a90bf651..d0737206f 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -5807,8 +5807,6 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12) SDL_assert(!VideoTexture20); /* either a new window or we destroyed all this */ SDL_assert(!VideoRenderer20); - FIXME("If we're using logical scaling, we can turn off depth buffer, alpha, etc, since we'll make our own and only need an RGB color buffer for the window."); - if (!VideoGLContext20) { VideoGLContext20 = SDL20_GL_CreateContext(VideoWindow20); if (!VideoGLContext20) { From 812d58fb1de30bb94dd89f76e838f1884284bcc1 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 19 Aug 2022 17:20:10 -0400 Subject: [PATCH 275/606] video: Optimize temporarily saving of dest alpha for a blit. Before we save the original alpha values of the whole surface, now only save off the rectangle being blitted. Reference Issue #143. --- src/SDL12_compat.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index d0737206f..cba209ca3 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -5969,7 +5969,7 @@ SDL_GetVideoSurface(void) } static int -SaveDestAlpha(SDL12_Surface *src12, SDL12_Surface *dst12, Uint8 **retval) +SaveDestAlpha(SDL12_Surface *src12, SDL12_Surface *dst12, const SDL12_Rect *dstrect12, Uint8 **retval) { /* The 1.2 docs say this: * RGBA->RGBA: @@ -5982,14 +5982,12 @@ SaveDestAlpha(SDL12_Surface *src12, SDL12_Surface *dst12, Uint8 **retval) Uint8 *dstalpha = NULL; const SDL_bool save_dstalpha = ((src12->flags & SDL12_SRCALPHA) && dst12->format->Amask && ((src12->format->alpha != 255) || src12->format->Amask)) ? SDL_TRUE : SDL_FALSE; - FIXME("This should only save the dst rect in use"); - if (save_dstalpha) { Uint8 *dptr; int x, y; - const int w = dst12->w; - const int h = dst12->h; + const int w = dstrect12->w; + const int h = dstrect12->h; const Uint32 amask = dst12->format->Amask; const Uint32 ashift = dst12->format->Ashift; @@ -6004,6 +6002,7 @@ SaveDestAlpha(SDL12_Surface *src12, SDL12_Surface *dst12, Uint8 **retval) if (dst12->format->BytesPerPixel == 2) { const Uint16 *sptr = (const Uint16 *) dst12->pixels; + sptr += ((dst12->pitch / 2) * dstrect12->y) + dstrect12->x; for (y = 0; y < h; y++) { for (x = 0; x < w; x++) { *(dptr++) = (Uint8) ((sptr[x] & amask) >> ashift); @@ -6012,6 +6011,7 @@ SaveDestAlpha(SDL12_Surface *src12, SDL12_Surface *dst12, Uint8 **retval) } } else if (dst12->format->BytesPerPixel == 4) { const Uint32 *sptr = (const Uint32 *) dst12->pixels; + sptr += ((dst12->pitch / 4) * dstrect12->y) + dstrect12->x; for (y = 0; y < h; y++) { for (x = 0; x < w; x++) { *(dptr++) = (Uint8) ((sptr[x] & amask) >> ashift); @@ -6028,7 +6028,7 @@ SaveDestAlpha(SDL12_Surface *src12, SDL12_Surface *dst12, Uint8 **retval) } static void -RestoreDestAlpha(SDL12_Surface *dst12, Uint8 *dstalpha) +RestoreDestAlpha(SDL12_Surface *dst12, Uint8 *dstalpha, const SDL12_Rect *dstrect12) { if (dstalpha) { int x, y; @@ -6042,6 +6042,7 @@ RestoreDestAlpha(SDL12_Surface *dst12, Uint8 *dstalpha) if (dst12->format->BytesPerPixel == 2) { Uint16 *dptr = (Uint16 *) dst12->pixels; + dptr += ((dst12->pitch / 2) * dstrect12->y) + dstrect12->x; for (y = 0; y < h; y++) { for (x = 0; x < w; x++) { dptr[x] = (Uint16) ((dptr[x] & ~amask) | ((((Uint16) *(sptr++)) << ashift) & amask)); @@ -6050,6 +6051,7 @@ RestoreDestAlpha(SDL12_Surface *dst12, Uint8 *dstalpha) } } else if (dst12->format->BytesPerPixel == 4) { Uint32 *dptr = (Uint32 *) dst12->pixels; + dptr += ((dst12->pitch / 4) * dstrect12->y) + dstrect12->x; for (y = 0; y < h; y++) { for (x = 0; x < w; x++) { dptr[x] = (dptr[x] & ~amask) | ((((Uint32) *(sptr++)) << ashift) & amask); @@ -6072,7 +6074,7 @@ SDL_UpperBlit(SDL12_Surface *src12, SDL12_Rect *srcrect12, SDL12_Surface *dst12, if ((src12 == NULL) || (dst12 == NULL)) { return SDL20_SetError("SDL_UpperBlit: passed a NULL surface"); - } else if (SaveDestAlpha(src12, dst12, &dstalpha) < 0) { + } else if (SaveDestAlpha(src12, dst12, dstrect12, &dstalpha) < 0) { return -1; } @@ -6081,7 +6083,7 @@ SDL_UpperBlit(SDL12_Surface *src12, SDL12_Rect *srcrect12, SDL12_Surface *dst12, dst12->surface20, dstrect12 ? Rect12to20(dstrect12, &dstrect20) : NULL); - RestoreDestAlpha(dst12, dstalpha); + RestoreDestAlpha(dst12, dstalpha, dstrect12); if (dstrect12) { Rect20to12(&dstrect20, dstrect12); @@ -6097,7 +6099,7 @@ SDL_LowerBlit(SDL12_Surface *src12, SDL12_Rect *srcrect12, SDL12_Surface *dst12, SDL_Rect srcrect20, dstrect20; int retval; - if (SaveDestAlpha(src12, dst12, &dstalpha) < 0) { + if (SaveDestAlpha(src12, dst12, dstrect12, &dstalpha) < 0) { return -1; } @@ -6106,7 +6108,7 @@ SDL_LowerBlit(SDL12_Surface *src12, SDL12_Rect *srcrect12, SDL12_Surface *dst12, dst12->surface20, dstrect12 ? Rect12to20(dstrect12, &dstrect20) : NULL); - RestoreDestAlpha(dst12, dstalpha); + RestoreDestAlpha(dst12, dstalpha, dstrect12); if (srcrect12) { Rect20to12(&srcrect20, srcrect12); From 72f4b9f7801c467ff108de48cc6731468af7ca87 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 19 Aug 2022 17:23:43 -0400 Subject: [PATCH 276/606] FIXME removal: these should be asserts, not FIXMEs. What alpha format would we have that isn't 2 or 4 bytes...? Reference Issue #143. --- src/SDL12_compat.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index cba209ca3..53a388485 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -6019,7 +6019,7 @@ SaveDestAlpha(SDL12_Surface *src12, SDL12_Surface *dst12, const SDL12_Rect *dstr sptr = (Uint32 *) (((Uint8 *) sptr) + pitch); } } else { - FIXME("Unhandled dest alpha"); + SDL_assert(!"Unhandled dest alpha"); } } @@ -6059,7 +6059,7 @@ RestoreDestAlpha(SDL12_Surface *dst12, Uint8 *dstalpha, const SDL12_Rect *dstrec dptr = (Uint32 *) (((Uint8 *) dptr) + pitch); } } else { - FIXME("Unhandled dest alpha"); + SDL_assert(!"Unhandled dest alpha"); } SDL20_free(dstalpha); } From d4ab8b57ed10d5dbcfa9a4a20d4c3621d0025d8c Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 26 Aug 2022 10:03:37 -0400 Subject: [PATCH 277/606] cdrom: if failed to load track, mark CD as as STOPPED, not TRAYEMPTY. --- src/SDL12_compat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 53a388485..c863327c9 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -8613,7 +8613,7 @@ FakeCdRomAudioCallback(AudioCallbackWrapperData *data, Uint8 *stream, int len, c if (data->cdrom_status == SDL12_CD_PLAYING) { /* go on to next track? */ const SDL_bool loaded = LoadCDTrack(++data->cdrom_cur_track, &data->cdrom_mp3); if (!loaded) { - data->cdrom_status = SDL12_CD_TRAYEMPTY; FIXME("Maybe just mark it stopped?"); + data->cdrom_status = SDL12_CD_STOPPED; } else { /* let new track fill out rest of callback. */ if (available < ((Uint32) len)) { FakeCdRomAudioCallback(data, stream + available, len - available, must_mix); From 184565a3ae07cbcc508d8427b51b5b5b3ca01f05 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 26 Aug 2022 10:42:42 -0400 Subject: [PATCH 278/606] video: Allow multiple overlays to render at a time. I don't know if this was ever used in the wild, or if this would have caused problems with actual hardware, but most (or all) of the platform APIs that 1.2 uses ostensibly supported it. Reference Issue #143. --- src/SDL12_compat.c | 77 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 62 insertions(+), 15 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index c863327c9..ffb5e2d42 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -932,6 +932,13 @@ typedef struct OpenGLEntryPoints } OpenGLEntryPoints; +typedef struct QueuedOverlayItem +{ + SDL12_Overlay *overlay12; + SDL12_Rect dstrect12; + struct QueuedOverlayItem *next; +} QueuedOverlayItem; + static Uint32 LinkedSDL2VersionInt = 0; static SDL_bool IsDummyVideo = SDL_FALSE; static VideoModeList *VideoModes = NULL; @@ -951,8 +958,8 @@ static Uint32 VideoSurfacePresentTicks = 0; static Uint32 VideoSurfaceLastPresentTicks = 0; static SDL_Surface *VideoConvertSurface20 = NULL; static SDL_GLContext VideoGLContext20 = NULL; -static SDL12_Overlay *QueuedDisplayOverlay12 = NULL; -static SDL12_Rect QueuedDisplayOverlayDstRect12; +static QueuedOverlayItem QueuedDisplayOverlays; /* the head node */ +static QueuedOverlayItem *QueuedDisplayOverlaysTail = &QueuedDisplayOverlays; static char *WindowTitle = NULL; static char *WindowIconTitle = NULL; static SDL_Surface *VideoIcon20 = NULL; @@ -2124,6 +2131,9 @@ Init12VidModes(void) } } + QueuedDisplayOverlays.next = NULL; + QueuedDisplayOverlaysTail = &QueuedDisplayOverlays; + return 0; } @@ -5217,6 +5227,8 @@ GetEnvironmentWindowPosition(int *x, int *y) static SDL12_Surface * EndVidModeCreate(void) { + QueuedOverlayItem *overlay; + if (OpenGLBlitTexture) { OpenGLFuncs.glDeleteTextures(1, &OpenGLBlitTexture); OpenGLBlitTexture = 0; @@ -5265,6 +5277,15 @@ EndVidModeCreate(void) MousePosition.x = 0; MousePosition.y = 0; + overlay = QueuedDisplayOverlays.next; + while (overlay != NULL) { + QueuedOverlayItem *next = overlay->next; + SDL_free(overlay); + overlay = next; + } + QueuedDisplayOverlays.next = NULL; + QueuedDisplayOverlaysTail = &QueuedDisplayOverlays; + return NULL; } @@ -6244,6 +6265,8 @@ SDL_DisplayFormatAlpha(SDL12_Surface *surface12) static void PresentScreen(void) { + QueuedOverlayItem *overlay; + if (!VideoRenderer20) { return; } @@ -6252,11 +6275,20 @@ PresentScreen(void) SDL20_RenderCopy(VideoRenderer20, VideoTexture20, NULL, NULL); /* Render any pending YUV overlay over the surface texture. */ - if (QueuedDisplayOverlay12) { - SDL12_YUVData *hwdata = (SDL12_YUVData *) QueuedDisplayOverlay12->hwdata; - SDL_Rect dstrect20; - SDL20_RenderCopy(VideoRenderer20, hwdata->texture20, NULL, Rect12to20(&QueuedDisplayOverlayDstRect12, &dstrect20)); - QueuedDisplayOverlay12 = NULL; + overlay = QueuedDisplayOverlays.next; + if (overlay) { + while (overlay != NULL) { + QueuedOverlayItem *next = overlay->next; + if (overlay->overlay12) { + SDL12_YUVData *hwdata = (SDL12_YUVData *) overlay->overlay12->hwdata; + SDL_Rect dstrect20; + SDL20_RenderCopy(VideoRenderer20, hwdata->texture20, NULL, Rect12to20(&overlay->dstrect12, &dstrect20)); + } + SDL_free(overlay); + overlay = next; + } + QueuedDisplayOverlays.next = NULL; + QueuedDisplayOverlaysTail = &QueuedDisplayOverlays; } SDL20_RenderPresent(VideoRenderer20); @@ -7154,6 +7186,7 @@ SDL_LockYUVOverlay(SDL12_Overlay *overlay12) DECLSPEC int SDLCALL SDL_DisplayYUVOverlay(SDL12_Overlay *overlay12, SDL12_Rect *dstrect12) { + QueuedOverlayItem *overlay; SDL12_YUVData *hwdata; if (!overlay12) { @@ -7162,6 +7195,8 @@ SDL_DisplayYUVOverlay(SDL12_Overlay *overlay12, SDL12_Rect *dstrect12) return SDL20_InvalidParamError("dstrect"); } else if (!VideoRenderer20) { return SDL20_SetError("No software screen surface available"); + } else if ((overlay = (QueuedOverlayItem *) SDL_malloc(sizeof (QueuedOverlayItem))) == NULL) { + return SDL20_OutOfMemory(); } hwdata = (SDL12_YUVData *) overlay12->hwdata; @@ -7194,10 +7229,19 @@ SDL_DisplayYUVOverlay(SDL12_Overlay *overlay12, SDL12_Rect *dstrect12) /* The app may or may not SDL_Flip() after this...queue this to render on the next present, and start a timer going to force a present, in case they don't. */ - FIXME("is it legal to display multiple yuv overlays?"); /* if so, this will need to be a list instead of a single pointer. */ - QueuedDisplayOverlay12 = overlay12; - SDL20_memcpy(&QueuedDisplayOverlayDstRect12, dstrect12, sizeof (SDL12_Rect)); - VideoSurfacePresentTicks = VideoSurfaceLastPresentTicks + GetDesiredMillisecondsPerFrame(); /* flip it later. */ + + overlay->overlay12 = overlay12; + SDL20_memcpy(&overlay->dstrect12, dstrect12, sizeof (SDL12_Rect)); + overlay->next = NULL; + + SDL_assert(QueuedDisplayOverlaysTail != NULL); + SDL_assert(QueuedDisplayOverlaysTail->next == NULL); + QueuedDisplayOverlaysTail->next = overlay; + QueuedDisplayOverlaysTail = overlay; + + if (!VideoSurfacePresentTicks) { + VideoSurfacePresentTicks = VideoSurfaceLastPresentTicks + GetDesiredMillisecondsPerFrame(); /* flip it later. */ + } return 0; } @@ -7214,11 +7258,14 @@ DECLSPEC void SDLCALL SDL_FreeYUVOverlay(SDL12_Overlay *overlay12) { if (overlay12) { - SDL12_YUVData *hwdata; - if (QueuedDisplayOverlay12 == overlay12) { - QueuedDisplayOverlay12 = NULL; + SDL12_YUVData *hwdata = (SDL12_YUVData *) overlay12->hwdata; + QueuedOverlayItem *overlay = QueuedDisplayOverlays.next; + while (overlay != NULL) { + if (overlay->overlay12 == overlay12) { + overlay->overlay12 = NULL; /* don't try to draw this later. */ + } } - hwdata = (SDL12_YUVData *) overlay12->hwdata; + SDL20_DestroyTexture(hwdata->texture20); SDL20_free(hwdata->pixelbuf); SDL20_free(overlay12); From 10fe724eb2698f6b2925db1421a8c5bb6af7c8b7 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 26 Aug 2022 11:21:35 -0400 Subject: [PATCH 279/606] timer: Keep a list of valid timers so SDL_RemoveTimer can't crash. This is how classic SDL 1.2 behaves, too. Reference Issue #143. --- src/SDL12_compat.c | 101 +++++++++++++++++++++++++++++++++------------ test/testtimer.c | 7 ++++ 2 files changed, 81 insertions(+), 27 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index ffb5e2d42..02794a82b 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -931,7 +931,6 @@ typedef struct OpenGLEntryPoints #include "SDL20_syms.h" } OpenGLEntryPoints; - typedef struct QueuedOverlayItem { SDL12_Overlay *overlay12; @@ -939,6 +938,27 @@ typedef struct QueuedOverlayItem struct QueuedOverlayItem *next; } QueuedOverlayItem; +typedef struct SDL12_TimerID_Data +{ + SDL_TimerID timer_id; + SDL12_NewTimerCallback callback; + void *param; + struct SDL12_TimerID_Data *next; + struct SDL12_TimerID_Data *prev; +} SDL12_TimerID_Data; + +/* This changed from an opaque pointer to an int in 2.0. */ +typedef SDL12_TimerID_Data *SDL12_TimerID; + +#define SDL12_MAXEVENTS 128 +typedef struct EventQueueType +{ + SDL12_SysWMmsg syswm_msg; /* save space for a copy of this in case we use it. */ + SDL12_Event event12; + struct EventQueueType *next; +} EventQueueType; + + static Uint32 LinkedSDL2VersionInt = 0; static SDL_bool IsDummyVideo = SDL_FALSE; static VideoModeList *VideoModes = NULL; @@ -1011,15 +1031,7 @@ static GLuint OpenGLLogicalScalingMultisampleDepth = 0; static GLuint OpenGLCurrentReadFBO = 0; static GLuint OpenGLCurrentDrawFBO = 0; static SDL_bool ForceGLSwapBufferContext = SDL_FALSE; - -#define SDL12_MAXEVENTS 128 -typedef struct EventQueueType -{ - SDL12_SysWMmsg syswm_msg; /* save space for a copy of this in case we use it. */ - SDL12_Event event12; - struct EventQueueType *next; -} EventQueueType; - +static SDL12_TimerID AddedTimers = NULL; /* we'll protect this with EventQueueMutex for laziness/convenience. */ static SDL_mutex *EventQueueMutex = NULL; static EventQueueType EventQueuePool[SDL12_MAXEVENTS]; static EventQueueType *EventQueueHead = NULL; @@ -7648,18 +7660,6 @@ SDL_KillThread(SDL_Thread *thread) "This program should be fixed. No thread was actually harmed.\n"); } -typedef struct SDL12_TimerID_Data -{ - SDL_TimerID timer_id; - SDL12_NewTimerCallback callback; - void *param; -} SDL12_TimerID_Data; - -/* This changed from an opaque pointer to an int in 2.0. */ -typedef SDL12_TimerID_Data *SDL12_TimerID; -SDL_COMPILE_TIME_ASSERT(timer, sizeof(SDL12_TimerID) >= sizeof(SDL_TimerID)); - - static Uint32 SDLCALL AddTimerCallback12(Uint32 interval, void *param) { @@ -7686,18 +7686,65 @@ SDL_AddTimer(Uint32 interval, SDL12_NewTimerCallback callback, void *param) return NULL; } + if (EventQueueMutex) { + SDL20_LockMutex(EventQueueMutex); + } + + data->prev = NULL; + data->next = AddedTimers; + if (AddedTimers) { + AddedTimers->prev = data; + } + AddedTimers = data; + + if (EventQueueMutex) { + SDL20_UnlockMutex(EventQueueMutex); + } + return data; } DECLSPEC SDL_bool SDLCALL SDL_RemoveTimer(SDL12_TimerID data) { - /* !!! FIXME: 1.2 will safely return SDL_FALSE if this is a - * bogus timer. This code will dereference a bogus pointer, though it handles NULL. */ - const SDL_bool retval = data ? SDL20_RemoveTimer(data->timer_id) : SDL_FALSE; - if (retval) { - SDL20_free(data); + SDL_bool retval = SDL_FALSE; + if (data) { + /* SDL 1.2 would make sure the pointer was valid and return false instead of crashing, so we check that too. */ + SDL12_TimerID i; + + if (EventQueueMutex) { + SDL20_LockMutex(EventQueueMutex); + } + + for (i = AddedTimers; i != NULL; i = i->next) { + if (i == data) { + break; + } + } + + if (i != NULL) { /* this is valid. */ + if (data->prev) { + data->prev->next = data->next; + } + if (data->next) { + data->next->prev = data->prev; + } + if (data == AddedTimers) { + AddedTimers = data->next; + } + retval = SDL_TRUE; + SDL20_RemoveTimer(data->timer_id); + } + + if (EventQueueMutex) { + SDL20_UnlockMutex(EventQueueMutex); + } + + if (retval) { + SDL20_free(data); + } } + return retval; } diff --git a/test/testtimer.c b/test/testtimer.c index 95608c120..9aaa8aaa3 100644 --- a/test/testtimer.c +++ b/test/testtimer.c @@ -82,6 +82,13 @@ int main(int argc, char *argv[]) SDL_RemoveTimer(t2); SDL_RemoveTimer(t3); + printf("Removing bogus timer..."); + if (SDL_RemoveTimer(t1)) { + printf("UHOH, SHOULD HAVE FAILED\n"); + } else { + printf("OK!\n"); + } + SDL_Quit(); return(0); } From 807814398fb5bcd861eb2891e83fcb8421cd0a24 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 26 Aug 2022 11:23:26 -0400 Subject: [PATCH 280/606] testtimer.c: Fixed tabs. --- test/testtimer.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/testtimer.c b/test/testtimer.c index 9aaa8aaa3..591133995 100644 --- a/test/testtimer.c +++ b/test/testtimer.c @@ -84,10 +84,10 @@ int main(int argc, char *argv[]) printf("Removing bogus timer..."); if (SDL_RemoveTimer(t1)) { - printf("UHOH, SHOULD HAVE FAILED\n"); - } else { - printf("OK!\n"); - } + printf("UHOH, SHOULD HAVE FAILED\n"); + } else { + printf("OK!\n"); + } SDL_Quit(); return(0); From 19f67e2e5c987526ea1c1b6c4d361f87494b6ad2 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 26 Aug 2022 11:30:11 -0400 Subject: [PATCH 281/606] overlay: use nearest-neighbor scaling for YUV overlay rendering. Classic SDL 1.2 appears to scale YUV overlays with nearest as well, so testoverlay2 becomes blocky, whereas previously sdl12-compat was making it blurry. --- src/SDL12_compat.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 02794a82b..4a3c73fd7 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -7097,6 +7097,7 @@ SDL_CreateYUVOverlay(int w, int h, Uint32 format12, SDL12_Surface *display12) rendering anyhow, we always make an SDL_Texture in here and draw over the screen pixels, in hopes that the GPU gives us a boost here. */ + const char *old_scale_quality = SDL20_GetHint(SDL_HINT_RENDER_SCALE_QUALITY); SDL12_Overlay *retval = NULL; SDL12_YUVData *hwdata = NULL; Uint32 format20 = 0; @@ -7150,7 +7151,9 @@ SDL_CreateYUVOverlay(int w, int h, Uint32 format12, SDL12_Surface *display12) hwdata->pitches[0] = w * 2; } + SDL20_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "0"); hwdata->texture20 = SDL20_CreateTexture(VideoRenderer20, format20, SDL_TEXTUREACCESS_STREAMING, w, h); + SDL20_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, old_scale_quality); if (!hwdata->texture20) { SDL20_free(hwdata->pixelbuf); SDL20_free(retval); From 7e74e1e7887d2cc46a5938298011773199e45155 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 26 Aug 2022 13:56:12 -0400 Subject: [PATCH 282/606] video: If drawing the same overlay twice in a frame, SDL_Flip() first. This will update the screen with the current surface contents and the existing overlay on top of it. This is sort of a hack, but probably closer to how this would have to work in real life for this corner case, which you can see in test/testoverlay.c ... in practice, basically everything that does this does so with an event loop, and code for animation timing--not to mention using a single overlay per frame, so this is really getting into the pathological what-ifs weeds, mostly. But now testoverlay.c works and nothing else should break, I think. Fixes #193. --- src/SDL12_compat.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 4a3c73fd7..b1f9ba863 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -7210,7 +7210,16 @@ SDL_DisplayYUVOverlay(SDL12_Overlay *overlay12, SDL12_Rect *dstrect12) return SDL20_InvalidParamError("dstrect"); } else if (!VideoRenderer20) { return SDL20_SetError("No software screen surface available"); - } else if ((overlay = (QueuedOverlayItem *) SDL_malloc(sizeof (QueuedOverlayItem))) == NULL) { + } + + for (overlay = QueuedDisplayOverlays.next; overlay != NULL; overlay = overlay->next) { + if (overlay->overlay12 == overlay12) { /* trying to draw the same overlay twice in one frame? Dump the current surface and overlays to the screen now. */ + SDL_Flip(VideoSurface12); + break; + } + } + + if ((overlay = (QueuedOverlayItem *) SDL_malloc(sizeof (QueuedOverlayItem))) == NULL) { return SDL20_OutOfMemory(); } From 639a0e7bd33e3bd8d1ab796ad7592367c258f0f8 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 26 Aug 2022 14:06:33 -0400 Subject: [PATCH 283/606] video: Always process and save off the surface from SDL_WM_SetIcon(). Previously, if there was already a window, we'd just pass it through to SDL2's SDL_SetWindowIcon(), but: - This way if we destroy the window for various reasons (like recreating it because SDL_SetVideoMode is changing the format, etc), we'll be able to reset the icon, which we couldn't before. - Before, there were two paths: one where we process the icon before handing it to SDL2 and one where we didn't. Notably, before, existing windows would ignore the mask passed to SDL_WM_SetIcon. This was probably a lot of explanation for what was an accidental line of code instead of an intentional but buggy design decision. :) Fixes #191. --- src/SDL12_compat.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index b1f9ba863..a69d5dc8b 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -6635,11 +6635,6 @@ SDL_WM_SetIcon(SDL12_Surface *icon12, Uint8 *mask) int bpp; int ret; - if (VideoWindow20) { - SDL20_SetWindowIcon(VideoWindow20, icon12->surface20); - return; - } - /* take the mask and zero out those alpha values. */ oldmode = SDL_BLENDMODE_NONE; if (SDL20_GetSurfaceBlendMode(icon12->surface20, &oldmode) < 0) { @@ -6662,7 +6657,6 @@ SDL_WM_SetIcon(SDL12_Surface *icon12, Uint8 *mask) const int h = icon12->h; const int mpitch = (w + 7) / 8; Uint32 *ptr = (Uint32 *) icon20->pixels; - int x, y; SDL_assert(icon20->format->BytesPerPixel == 4); @@ -6685,6 +6679,10 @@ SDL_WM_SetIcon(SDL12_Surface *icon12, Uint8 *mask) SDL20_FreeSurface(VideoIcon20); VideoIcon20 = icon20; } + + if (VideoWindow20) { + SDL20_SetWindowIcon(VideoWindow20, VideoIcon20); + } } DECLSPEC int SDLCALL From 70106dd3c2f8b3ebf3fe428a7001185b7dca42f3 Mon Sep 17 00:00:00 2001 From: Joshua Root Date: Mon, 29 Aug 2022 10:20:37 +1000 Subject: [PATCH 284/606] Make include logic closer to real SDL 1.2 This should offer better compatibility in some cases. --- include/SDL/SDL_stdinc.h | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/include/SDL/SDL_stdinc.h b/include/SDL/SDL_stdinc.h index aa070c4cb..d604b0392 100644 --- a/include/SDL/SDL_stdinc.h +++ b/include/SDL/SDL_stdinc.h @@ -83,10 +83,9 @@ SDL_COMPILE_TIME_ASSERT(enum, sizeof(SDL_DUMMY_ENUM) == sizeof(int)); #ifdef HAVE_STDIO_H #include #endif -#ifdef HAVE_STDLIB_H +#if defined(HAVE_STDLIB_H) #include -#endif -#ifdef HAVE_MALLOC_H +#elif defined(HAVE_MALLOC_H) #include #endif #ifdef HAVE_STDDEF_H @@ -101,10 +100,9 @@ SDL_COMPILE_TIME_ASSERT(enum, sizeof(SDL_DUMMY_ENUM) == sizeof(int)); #ifdef HAVE_STRINGS_H #include #endif -#ifdef HAVE_INTTYPES_H +#if defined(HAVE_INTTYPES_H) #include -#endif -#ifdef HAVE_STDINT_H +#elif defined(HAVE_STDINT_H) #include #endif #ifdef HAVE_CTYPE_H From 1f4d16e19af2f5f25e1cf574db5f2de8fc6ae4ea Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sun, 28 Aug 2022 23:01:30 -0400 Subject: [PATCH 285/606] Fixed a typo in a comment. --- src/SDL12_compat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index a69d5dc8b..be436a85a 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -5629,7 +5629,7 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12) /* default use_highdpi to false for OpenGL windows when not using OpenGL scaling as legacy OpenGL applications are unlikely to support high-DPI setups properly. (They often use the window size to determine - the resolute in some or all parts of their code.) Because OpenGL scaling + the resolution in some or all parts of their code.) Because OpenGL scaling is never used for windows, it is always false there. */ use_highdpi = (flags12 & SDL12_FULLSCREEN) ? use_gl_scaling : SDL_FALSE; } From bf38589203f7a667877b9fe5233a4cc13ff4c651 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 29 Aug 2022 00:10:12 -0400 Subject: [PATCH 286/606] video: Added the option to scale non-fullscreen windows. Reference Issue #143. --- README.md | 13 +++++++++++++ src/SDL12_compat.c | 45 ++++++++++++++++++++++++++++++++++++++------- src/SDL20_syms.h | 1 + 3 files changed, 52 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 92168421a..f6f489fbc 100644 --- a/README.md +++ b/README.md @@ -208,6 +208,19 @@ The available options are: use this hint. If there is no known game controller mapping for a joystick, and this hint is in use, it will not be listed as an availble device. +- SDL12COMPAT_WINDOW_SCALING: + When creating non-fullscreen, non-resizable windows, use this variable to + size the window differently. If, for example, you have a 4K monitor and the + game is running in a window the size of a postage stamp, you might set this + to 2 to double the size of the window. Fractional values work, so "1.5" + might be a more-pleasing value on your hardware. You can even shrink the + window with values less than 1.0! When scaling a window like this, + sdl12-compat will use all the usual scaling options + (SDL12COMPAT_OPENGL_SCALING, SDL12COMPAT_SCALE_METHOD, etc). If sdl12-compat + can't scale the contents of the window for various technical reasons, it + will create the window at the originally-requested size. If this variable + isn't specified, it defaults to 1.0 (no scaling). + - SDL_MOUSE_RELATIVE_SCALING: If enabled, relative mouse motion is scaled when the application is running at a non-native resolution. This may be required with some diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index be436a85a..12740e5d4 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1301,6 +1301,18 @@ SDL12Compat_GetHintBoolean(const char *name, SDL_bool default_value) return (SDL20_atoi(val) != 0) ? SDL_TRUE : SDL_FALSE; } +static float +SDL12Compat_GetHintFloat(const char *name, float default_value) +{ + const char *val = SDL12Compat_GetHint(name); + + if (!val) { + return default_value; + } + + return (float) SDL20_atof(val); +} + static void SDL12Compat_PrintQuirks(void) { @@ -5605,11 +5617,13 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12) SDL_DisplayMode dmode; Uint32 fullscreen_flags20 = 0; Uint32 appfmt; + float window_size_scaling = SDL12Compat_GetHintFloat("SDL12COMPAT_WINDOW_SCALING", 1.0f); SDL_bool use_gl_scaling = SDL_FALSE; SDL_bool use_highdpi = SDL_TRUE; SDL_bool fix_bordless_fs_win = SDL_TRUE; + int scaled_width = width; + int scaled_height = height; - FIXME("Should we offer scaling for windowed modes, too?"); if (flags12 & SDL12_OPENGL) { /* For now we default GL scaling to ENABLED. If an app breaks or is linked directly to glBindFramebuffer, they'll need to turn it off with this environment variable. @@ -5778,6 +5792,19 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12) fullscreen_flags20 |= SDL_WINDOW_FULLSCREEN_DESKTOP; } + if (window_size_scaling <= 0.0f) { + window_size_scaling = 1.0f; /* bogus value, reset to default */ + } else if (flags12 & SDL12_RESIZABLE) { + window_size_scaling = 1.0f; /* assume that resizable windows are already prepared to handle whatever without scaling. */ + } else if ((fullscreen_flags20 & SDL_WINDOW_FULLSCREEN_DESKTOP) != 0) { + window_size_scaling = 1.0f; /* setting the window to fullscreen or fullscreen_desktop? Don't scale it. */ + } else if ((flags12 & SDL12_OPENGL) && !use_gl_scaling) { + window_size_scaling = 1.0f; /* OpenGL but not doing GL scaling? Don't allow window size scaling. */ + } else { + scaled_width = (int) (window_size_scaling * width); + scaled_height = (int) (window_size_scaling * height); + } + if (!VideoWindow20) { /* create it */ int x = SDL_WINDOWPOS_UNDEFINED, y = SDL_WINDOWPOS_UNDEFINED; Uint32 flags20 = fullscreen_flags20; @@ -5796,7 +5823,7 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12) SDL20_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, OpenGLLogicalScalingSamples); } - VideoWindow20 = SDL20_CreateWindow(WindowTitle, x, y, width, height, flags20); + VideoWindow20 = SDL20_CreateWindow(WindowTitle, x, y, scaled_width, scaled_height, flags20); if (!VideoWindow20) { return EndVidModeCreate(); } @@ -5804,10 +5831,10 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12) SDL20_SetWindowIcon(VideoWindow20, VideoIcon20); } } else { /* resize it */ - SDL20_SetWindowSize(VideoWindow20, width, height); + SDL20_SetWindowSize(VideoWindow20, scaled_width, scaled_height); SDL20_SetWindowFullscreen(VideoWindow20, fullscreen_flags20); /* This second SetWindowSize is a workaround for an SDL2 bug, see https://github.com/libsdl-org/sdl12-compat/issues/148 */ - SDL20_SetWindowSize(VideoWindow20, width, height); + SDL20_SetWindowSize(VideoWindow20, scaled_width, scaled_height); SDL20_SetWindowBordered(VideoWindow20, (flags12 & SDL12_NOFRAME) ? SDL_FALSE : SDL_TRUE); SDL20_SetWindowResizable(VideoWindow20, (flags12 & SDL12_RESIZABLE) ? SDL_TRUE : SDL_FALSE); } @@ -5853,12 +5880,16 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12) /* Try to set up a logical scaling */ if (use_gl_scaling) { if (!InitializeOpenGLScaling(width, height)) { + const SDL_bool was_fullscreen = ((fullscreen_flags20 & SDL_WINDOW_FULLSCREEN_DESKTOP) != 0) ? SDL_TRUE : SDL_FALSE; + window_size_scaling = 1.0f; use_gl_scaling = SDL_FALSE; fullscreen_flags20 &= ~SDL_WINDOW_FULLSCREEN_DESKTOP; SDL20_SetWindowFullscreen(VideoWindow20, fullscreen_flags20); - SDL20_SetWindowSize(VideoWindow20, width, height); - fullscreen_flags20 |= SDL_WINDOW_FULLSCREEN; - SDL20_SetWindowFullscreen(VideoWindow20, fullscreen_flags20); + SDL20_SetWindowSize(VideoWindow20, width, height); /* not scaled_width, scaled_height */ + if (was_fullscreen) { + fullscreen_flags20 |= SDL_WINDOW_FULLSCREEN; + SDL20_SetWindowFullscreen(VideoWindow20, fullscreen_flags20); + } } } diff --git a/src/SDL20_syms.h b/src/SDL20_syms.h index 84087ffc0..2484cfb3b 100644 --- a/src/SDL20_syms.h +++ b/src/SDL20_syms.h @@ -275,6 +275,7 @@ SDL20_SYM_PASSTHROUGH(void,qsort,(void *a, size_t b, size_t c, int (SDLCALL *d)( SDL20_SYM_PASSTHROUGH(void *,memset,(void *a, int b, size_t c),(a,b,c),return) SDL20_SYM_PASSTHROUGH(void *,memcpy,(void *a, const void *b, size_t c),(a,b,c),return) SDL20_SYM(void *,memmove,(void *a, const void *b, size_t c),(a,b,c),return) +SDL20_SYM(double,atof,(const char *a),(a),return) SDL20_SYM_PASSTHROUGH(int,memcmp,(const void *a, const void *b, size_t c),(a,b,c),return) SDL20_SYM_PASSTHROUGH(size_t,strlen,(const char *a),(a),return) From b42bcef599891c58018e543c4e01e0ccac1a67f8 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 29 Aug 2022 10:57:32 -0400 Subject: [PATCH 287/606] video: Add basic support for SDL_WINDOWID. This is not perfect (and probably can't be), but this is better than nothing. Fixes #192. --- src/SDL12_compat.c | 24 ++++++++++++++++++++---- src/SDL20_syms.h | 1 + 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 12740e5d4..6cbb48b63 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -5623,6 +5623,7 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12) SDL_bool fix_bordless_fs_win = SDL_TRUE; int scaled_width = width; int scaled_height = height; + const char *fromwin_env = NULL; if (flags12 & SDL12_OPENGL) { /* For now we default GL scaling to ENABLED. If an app breaks or is linked directly @@ -5654,8 +5655,6 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12) ForceGLSwapBufferContext = SDL12Compat_GetHintBoolean("SDL12COMPAT_FORCE_GL_SWAPBUFFER_CONTEXT", SDL_FALSE); - FIXME("currently ignores SDL_WINDOWID, which we could use with SDL_CreateWindowFrom ...?"); - flags12 &= ~SDL12_HWACCEL; /* just in case - https://github.com/libsdl-org/SDL-1.2/issues/817 */ /* SDL_SetVideoMode() implicitly inits if necessary. */ @@ -5792,7 +5791,11 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12) fullscreen_flags20 |= SDL_WINDOW_FULLSCREEN_DESKTOP; } - if (window_size_scaling <= 0.0f) { + fromwin_env = SDL20_getenv("SDL_WINDOWID"); + + if (fromwin_env) { + window_size_scaling = 1.0f; /* don't scale for external windows */ + } else if (window_+size_scaling <= 0.0f) { window_size_scaling = 1.0f; /* bogus value, reset to default */ } else if (flags12 & SDL12_RESIZABLE) { window_size_scaling = 1.0f; /* assume that resizable windows are already prepared to handle whatever without scaling. */ @@ -5805,7 +5808,20 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12) scaled_height = (int) (window_size_scaling * height); } - if (!VideoWindow20) { /* create it */ + if (fromwin_env) { + char *endp = NULL; + const Uint64 windowid = SDL_strtoull(fromwin_env, &endp, 0); + if ((*fromwin_env == '\0') || (*endp != '\0')) { + SDL20_SetError("Invalid SDL_WINDOWID"); + return EndVidModeCreate(); + } else { + EndVidModeCreate(); + VideoWindow20 = SDL20_CreateWindowFrom((void *) (size_t) (windowid)); + if (!VideoWindow20) { + return EndVidModeCreate(); + } + } + } else if (!VideoWindow20) { /* create it */ int x = SDL_WINDOWPOS_UNDEFINED, y = SDL_WINDOWPOS_UNDEFINED; Uint32 flags20 = fullscreen_flags20; if (flags12 & SDL12_OPENGL) { flags20 |= SDL_WINDOW_OPENGL; } diff --git a/src/SDL20_syms.h b/src/SDL20_syms.h index 2484cfb3b..b4b7d04fc 100644 --- a/src/SDL20_syms.h +++ b/src/SDL20_syms.h @@ -85,6 +85,7 @@ SDL20_SYM(void,EnableScreenSaver,(void),(),) SDL20_SYM(void,DisableScreenSaver,(void),(),) SDL20_SYM(SDL_Window *,CreateWindow,(const char *a, int b, int c, int d, int e, Uint32 f),(a,b,c,d,e,f),return) +SDL20_SYM(SDL_Window *,CreateWindowFrom,(const void *a),(a),return) SDL20_SYM(void,DestroyWindow,(SDL_Window *a),(a),) SDL20_SYM(void,SetWindowIcon,(SDL_Window *a,SDL_Surface *b),(a,b),) SDL20_SYM(int,UpdateWindowSurface,(SDL_Window *a),(a),return) From 9d5cfb60d45bcd9a8fcbf5359dd7276590594924 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 29 Aug 2022 11:09:31 -0400 Subject: [PATCH 288/606] Patched to compile. Bumped the keyboard right before committing, sorry! --- src/SDL12_compat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 6cbb48b63..ab7765735 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -5795,7 +5795,7 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12) if (fromwin_env) { window_size_scaling = 1.0f; /* don't scale for external windows */ - } else if (window_+size_scaling <= 0.0f) { + } else if (window_size_scaling <= 0.0f) { window_size_scaling = 1.0f; /* bogus value, reset to default */ } else if (flags12 & SDL12_RESIZABLE) { window_size_scaling = 1.0f; /* assume that resizable windows are already prepared to handle whatever without scaling. */ From 0c77cafc595f6b38bd7e5e11aea9b0f3f95b87db Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 30 Aug 2022 13:16:13 -0400 Subject: [PATCH 289/606] events: Only look at first codepoint of TEXTINPUT, use it if keypress matches. SDL 1.2 wasn't complicated (or correct) about the `unicode` field on KEYDOWN events, this feels like it matches more closely. We _might_ revert this change, though, because this is taking a sledgehammer to something pretty delicate. --- src/SDL12_compat.c | 33 ++++----------------------------- 1 file changed, 4 insertions(+), 29 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index ab7765735..f529f140f 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -4458,35 +4458,10 @@ EventFilter20to12(void *data, SDL_Event *event20) case SDL_TEXTEDITING: return 1; case SDL_TEXTINPUT: { char *text = event20->text.text; - int codePoint; - while ((codePoint = DecodeUTF8Char(&text)) != 0) { - if (codePoint > 0xFFFF) { - /* We need to send a UTF-16 surrogate pair. */ - Uint16 firstChar = ((codePoint - 0x10000) >> 10) + 0xD800; - Uint16 secondChar = ((codePoint - 0x10000) & 0x3FF) + 0xDC00; - event12.type = SDL12_KEYDOWN; - event12.key.state = SDL12_PRESSED; - event12.key.keysym.scancode = 0; - event12.key.keysym.sym = SDLK12_UNKNOWN; - event12.key.keysym.unicode = firstChar; - if (!FlushPendingKeydownEvent(firstChar)) { - PushEventIfNotFiltered(&event12); - } - event12.key.keysym.unicode = secondChar; - PushEventIfNotFiltered(&event12); - } else { - if (!FlushPendingKeydownEvent(codePoint)) { - event12.type = SDL12_KEYDOWN; - event12.key.state = SDL12_PRESSED; - event12.key.keysym.scancode = 0; - event12.key.keysym.sym = SDLK12_UNKNOWN; - event12.key.keysym.unicode = codePoint; - PushEventIfNotFiltered(&event12); - } - } - } - } - return 1; + const int codePoint = DecodeUTF8Char(&text); + FlushPendingKeydownEvent(codePoint); + return 1; + } case SDL_MOUSEMOTION: event12.type = SDL12_MOUSEMOTION; From f5d35879bcb02caac53c1b5bcedd22f43fb3fe4d Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 30 Aug 2022 13:18:52 -0400 Subject: [PATCH 290/606] input: Implement SDL 1.2 style key repeat. Reference Issue #143. --- src/SDL12_compat.c | 64 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 55 insertions(+), 9 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index f529f140f..f340fc3b1 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -984,7 +984,10 @@ static char *WindowTitle = NULL; static char *WindowIconTitle = NULL; static SDL_Surface *VideoIcon20 = NULL; static int EnabledUnicode = 0; -static SDL_bool EnabledKeyRepeat = SDL_TRUE; +static Uint32 KeyRepeatNextTicks = 0; +static Uint32 KeyRepeatDelay = 0; +static Uint32 KeyRepeatInterval = 0; +static SDL12_Event KeyRepeatEvent; /* Windows SDL1.2 never uses translated keyboard layouts for compatibility with DirectInput, which didn't support them. Other platforms (MacOS, Linux) seem to, but with varying levels of bugginess. So default to Translated Layouts on @@ -2200,6 +2203,8 @@ HasWmAvailable(const char *driver) return 0; } +DECLSPEC int SDLCALL SDL_EnableKeyRepeat(int delay, int interval); + static int Init12Video(void) { @@ -2240,6 +2245,8 @@ Init12Video(void) SupportSysWM = SDL_FALSE; #endif + SDL_EnableKeyRepeat(0, 0); + SDL20_DelEventWatch(EventFilter20to12, NULL); SDL20_AddEventWatch(EventFilter20to12, NULL); @@ -2427,6 +2434,8 @@ Quit12Video(void) { int i; + SDL_EnableKeyRepeat(0, 0); + SDL20_FreeSurface(VideoIcon20); VideoIcon20 = NULL; @@ -4247,6 +4256,12 @@ static int FlushPendingKeydownEvent(Uint32 unicode) PendingKeydownEvent.key.keysym.unicode = unicode; PushEventIfNotFiltered(&PendingKeydownEvent); + + if (KeyRepeatDelay) { + SDL20_memcpy(&KeyRepeatEvent, &PendingKeydownEvent, sizeof (SDL12_Event)); + KeyRepeatNextTicks = SDL20_GetTicks() + KeyRepeatDelay; + } + /* Reset the event. */ SDL20_memset(&PendingKeydownEvent, 0, sizeof (SDL12_Event)); @@ -4377,9 +4392,16 @@ EventFilter20to12(void *data, SDL_Event *event20) event12.key.keysym.sym = Scancode20toKeysym12(event20->key.keysym.scancode); } + if (KeyRepeatNextTicks) { + SDL_assert(KeyRepeatEvent.type == SDL12_KEYDOWN); + if (KeyRepeatEvent.key.keysym.sym == event12.key.keysym.sym) { + KeyRepeatNextTicks = 0; + } + } + KeyState[event12.key.keysym.sym] = event20->key.state; - event12.type = (event20->type == SDL_KEYDOWN) ? SDL12_KEYDOWN : SDL12_KEYUP; + event12.type = SDL12_KEYUP; event12.key.which = 0; event12.key.state = event20->key.state; /* turns out that some apps actually made use of the hardware scancodes (checking for platform beforehand) */ @@ -4393,7 +4415,7 @@ EventFilter20to12(void *data, SDL_Event *event20) case SDL_KEYDOWN: FlushPendingKeydownEvent(0); - if (event20->key.repeat && !EnabledKeyRepeat) { + if (event20->key.repeat) { return 1; /* ignore 2.0-style key repeat events */ } @@ -6590,6 +6612,25 @@ SDL_Flip(SDL12_Surface *surface12) return 0; } +static void +HandleKeyRepeat(void) +{ + /* SDL 1.2 is a little weird about key repeat; it manages it itself + (so we can't use SDL2's key repeat), it only runs during PumpEvents + (so no AddTimer or separate thread to manage it), and it cares about + the last key pressed (so if a key is repeating and you press a new + one down, it stops repeating the first key). */ + if (KeyRepeatNextTicks) { + const Uint32 now = SDL20_GetTicks(); + SDL_assert(KeyRepeatEvent.type == SDL12_KEYDOWN); + if (SDL_TICKS_PASSED(now, KeyRepeatNextTicks)) { + /* these repeat from the current time in SDL 1.2, not consistently! */ + KeyRepeatNextTicks = now + KeyRepeatInterval; + PushEventIfNotFiltered(&KeyRepeatEvent); + } + } +} + DECLSPEC void SDLCALL SDL_PumpEvents(void) { @@ -6615,6 +6656,8 @@ SDL_PumpEvents(void) FlushPendingKeydownEvent(0); } + HandleKeyRepeat(); /* deal with SDL 1.2-style key repeat... */ + if (EventQueueMutex) { SDL20_UnlockMutex(EventQueueMutex); } @@ -7536,11 +7579,14 @@ SDL_GetGammaRamp(Uint16 *red, Uint16 *green, Uint16 *blue) DECLSPEC int SDLCALL SDL_EnableKeyRepeat(int delay, int interval) { - FIXME("Support non-default delay and interval for Key Repeat"); - (void) interval; - - EnabledKeyRepeat = (delay != 0) ? SDL_TRUE : SDL_FALSE; + if ((delay < 0) || (interval < 0)) { + return SDL20_SetError("Invalid key repeat values"); + } + KeyRepeatEvent.type = SDL12_NOEVENT; + KeyRepeatNextTicks = 0; + KeyRepeatDelay = (Uint32) delay; + KeyRepeatInterval = (Uint32) interval; return 0; } @@ -7548,10 +7594,10 @@ DECLSPEC void SDLCALL SDL_GetKeyRepeat(int *delay, int *interval) { if (delay) { - *delay = EnabledKeyRepeat ? SDL12_DEFAULT_REPEAT_DELAY : 0; + *delay = (int) KeyRepeatDelay; } if (interval) { - *interval = EnabledKeyRepeat ? SDL12_DEFAULT_REPEAT_INTERVAL : 0; + *interval = (int) KeyRepeatInterval; } } From 0dcdfe0fc9e2b61055dfc0681abc50df60a18620 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 30 Aug 2022 16:40:30 -0400 Subject: [PATCH 291/606] init: Deal with SDL 1.2 subsystem init vs SDL2. In 1.2 each subsystem has a flag that tracks if it's initialized, so quitting a subsystem once cancels all previous init attempts. In SDL2, each subsystem has a reference count. So keep a bitmask here that tracks 1.2-style init and only init SDL2 once. Reference Issue #143. --- src/SDL12_compat.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index f340fc3b1..9ef44c145 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -959,6 +959,7 @@ typedef struct EventQueueType } EventQueueType; +static Uint32 InitializedSubsystems20 = 0; static Uint32 LinkedSDL2VersionInt = 0; static SDL_bool IsDummyVideo = SDL_FALSE; static VideoModeList *VideoModes = NULL; @@ -2335,7 +2336,14 @@ SDL_InitSubSystem(Uint32 sdl12flags) have this problem, so we're ignoring the parachute until a reasonable need arises. */ - #define SETFLAG(flag) if (sdl12flags & SDL12_INIT_##flag) sdl20flags |= SDL_INIT_##flag + #define SETFLAG(flag) { \ + const Uint32 f12 = SDL12_INIT_##flag; \ + const Uint32 f20 = SDL_INIT_##flag; \ + if ((sdl12flags & f12) && ((InitializedSubsystems20 & f20) == 0)) { \ + sdl20flags |= f20; \ + } \ + } + SETFLAG(TIMER); SETFLAG(AUDIO); SETFLAG(VIDEO); @@ -2369,6 +2377,8 @@ SDL_InitSubSystem(Uint32 sdl12flags) Init12Joystick(); /* if this fails, we just won't report any sticks. */ } + InitializedSubsystems20 |= sdl20flags; + return rc; } @@ -2462,6 +2472,9 @@ Quit12Video(void) SDL20_DestroyMutex(EventQueueMutex); EventQueueMutex = NULL; } + + /* Shutdown the fake event thread. */ + EventThreadEnabled = SDL_FALSE; } DECLSPEC void SDLCALL @@ -2488,9 +2501,6 @@ SDL_QuitSubSystem(Uint32 sdl12flags) if (sdl12flags & SDL12_INIT_VIDEO) { Quit12Video(); - - /* Shutdown the fake event thread. */ - EventThreadEnabled = SDL_FALSE; } if (sdl12flags & SDL12_INIT_JOYSTICK) { @@ -2502,12 +2512,15 @@ SDL_QuitSubSystem(Uint32 sdl12flags) if ((SDL20_WasInit(0) == 0) && (!CDRomInit)) { SDL20_Quit(); } + + InitializedSubsystems20 &= ~sdl20flags; } DECLSPEC void SDLCALL SDL_Quit(void) { SDL_QuitSubSystem(SDL_WasInit(0) | SDL12_INIT_CDROM); + SDL_assert(InitializedSubsystems20 == 0); } DECLSPEC void SDLCALL @@ -8226,7 +8239,6 @@ InitializeCDSubsystem(void) { const char *cdpath; - FIXME("Is subsystem init reference counted in SDL 1.2?"); /* it is in SDL2, but I don't know for 1.2. */ if (CDRomInit) { return; } From ec3d9421e7a4f5b16d7650ae2608054459015d75 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 30 Aug 2022 23:45:43 -0400 Subject: [PATCH 292/606] FIXME removal: Give up on SDL 1.2 SDLK_(COMPOSE|BREAK|EURO) keycodes. SDLK_COMPOSE was only referenced in the x11 backend, as a sort of "I have nothing better to assign to this random set of keys." SDLK_BREAK is generally the same key as SDLK_PAUSE. SDLK_EURO appears to only be used by the 1.2 BeOS backend, and The Be Book can't identify a physical key that generates this keycode: https://www.haiku-os.org/legacy-docs/bebook/TheKeyboard_KeyCodes.html So nothing reasonable maps to these things (and if they _are_ reasonable, SDL2 doesn't report anything equivalent to them), so in the best case they aren't goign concerns, in the worst case we just pretend the user never pressed them. So the FIXME is simply removed. Reference Issue #143. --- src/SDL12_compat.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 9ef44c145..82085ce36 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -3951,7 +3951,6 @@ Keysym20to12(const SDL_Keycode keysym20) default: break; } - FIXME("nothing maps to SDLK12_COMPOSE, SDLK12_BREAK, or SDLK12_EURO ...?"); return SDLK12_UNKNOWN; } static SDL12Key From 4b33a6201c9e72b259146a3991409aea6595c967 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 30 Aug 2022 23:50:22 -0400 Subject: [PATCH 293/606] FIXME removal: Another FIXME about SDLK_BREAK and SDLK_EURO removed. See comments in previous commit. Reference Issue #143. --- src/SDL12_compat.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 82085ce36..aa2cbcccd 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -4093,7 +4093,6 @@ Scancode20toKeysym12(const SDL_Scancode scancode20) default: break; } - FIXME("nothing maps to SDLK12_BREAK, or SDLK12_EURO ...?"); FIXME("map some of the SDLK12_WORLD keys"); return SDLK12_UNKNOWN; } From 549d85b8dc5b47d95308df118735bc68170b7e00 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 30 Aug 2022 23:58:49 -0400 Subject: [PATCH 294/606] FIXME removal: ignore SDLK_WORLD keys when not translating keyboard layout. This is a lesser-used codepath that probably doesn't need this feature, which we probably can't supply in any reasonable way anyhow. Reference Issue #143. --- src/SDL12_compat.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index aa2cbcccd..a984ed429 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -4093,7 +4093,6 @@ Scancode20toKeysym12(const SDL_Scancode scancode20) default: break; } - FIXME("map some of the SDLK12_WORLD keys"); return SDLK12_UNKNOWN; } From d0a1dc92d2e234fd52b4cefae938e1b2efbdd8f0 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 31 Aug 2022 00:03:58 -0400 Subject: [PATCH 295/606] FIXME removal: this is janky but honestly good enough. --- src/SDL12_compat.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index a984ed429..3800956e9 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -8336,13 +8336,12 @@ SDL_CDOpen(int drive) return NULL; } - /* We should probably do a proper enumeration of this directory, - but that needs platform-specific code that SDL2 doesn't offer. + /* We would do a proper enumeration of this directory, but that + would need platform-specific code that SDL2 doesn't offer. readdir() is surprisingly hard to do without a bunch of different platform backends! We just open files until we fail to do so, and then stop. */ - FIXME("Can we do something more robust than this for directory enumeration?"); - for (;;) { + while (SDL_TRUE) { SDL_RWops *rw; drmp3_uint64 pcmframes; drmp3_uint32 samplerate; From ed299ba1772ee52c58b7817f3997101b5c79ff14 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 31 Aug 2022 00:23:23 -0400 Subject: [PATCH 296/606] cdrom: Allow fake data tracks to intersperse with audio. Reference Issue #143. --- src/SDL12_compat.c | 61 +++++++++++++++++++++++++++++++++------------- 1 file changed, 44 insertions(+), 17 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 3800956e9..6b5e22470 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -8309,6 +8309,7 @@ SDL_CDOpen(int drive) char *fullpath; drmp3 *mp3 = NULL; Uint32 total_track_offset = 0; + SDL_bool has_audio = SDL_FALSE; if (!ValidCDDriveIndex(drive)) { return NULL; @@ -8346,36 +8347,62 @@ SDL_CDOpen(int drive) drmp3_uint64 pcmframes; drmp3_uint32 samplerate; SDL12_CDtrack *track; - int c; char c0, c1; + SDL_bool fake_data_track = SDL_FALSE; + int c; + char c0, c1; /* we only report audio tracks, starting at 1... */ FIXME("Let there be fake data tracks"); c = retval->numtracks + 1; c0 = c / 10 + '0'; c1 = c % 10 + '0'; - SDL20_snprintf(fullpath, alloclen, "%s%strack%c%c.mp3", CDRomPath, DIRSEP, c0, c1); + + /* note that fake data track files just need to exist, they can be empty files. */ + SDL20_snprintf(fullpath, alloclen, "%s%strack%c%c.dat", CDRomPath, DIRSEP, c0, c1); rw = SDL20_RWFromFile(fullpath, "rb"); - if (!rw && c > 1) { - break; /* ok, we're done looking for more. */ + if (rw) { /* fake data track. */ + fake_data_track = SDL_TRUE; + SDL20_RWclose(rw); + rw = NULL; + } else { + SDL20_snprintf(fullpath, alloclen, "%s%strack%c%c.mp3", CDRomPath, DIRSEP, c0, c1); + rw = SDL20_RWFromFile(fullpath, "rb"); + /* if there isn't a track 1 specified, pretend it's a data track, which matches most games' needs. */ + if (!rw && (c == 0)) { + fake_data_track = SDL_TRUE; + } } + if (!rw && !fake_data_track) { + break; /* ok, we're done looking for more. */ + } track = &retval->track[retval->numtracks]; - if (!rw) { - track->type = 4; /* data track. E.g.: quake's audio starts at track 2. */ - } else { + if (!fake_data_track) { + SDL_assert(rw != NULL); if (!drmp3_init(mp3, mp3_sdlrwops_read, mp3_sdlrwops_seek, rw, NULL)) { SDL20_RWclose(rw); - break; /* ok, we're done looking for more. */ + rw = NULL; + fake_data_track = SDL_TRUE; /* congratulations, bogus or unsupported MP3, you just became data! */ + } else { + pcmframes = drmp3_get_pcm_frame_count(mp3); + samplerate = mp3->sampleRate; + FreeMp3(mp3); + rw = NULL; + + track->id = retval->numtracks; + track->type = 0; /* audio track. Data tracks are 4. */ + track->length = (Uint32) ((((double) pcmframes) / ((double) samplerate)) * CDAUDIO_FPS); + track->offset = total_track_offset; + total_track_offset += track->length; + + has_audio = SDL_TRUE; } - pcmframes = drmp3_get_pcm_frame_count(mp3); - samplerate = mp3->sampleRate; - FreeMp3(mp3); + } + + SDL_assert(rw == NULL); /* we should have dealt with this in all paths. */ - track->id = retval->numtracks; - track->type = 0; /* audio track. Data tracks are 4. */ - track->length = (Uint32) ((((double) pcmframes) / ((double) samplerate)) * CDAUDIO_FPS); - track->offset = total_track_offset; - total_track_offset += track->length; + if (fake_data_track) { + track->type = 4; /* data track. E.g.: quake's audio starts at track 2. */ } retval->numtracks++; @@ -8384,7 +8411,7 @@ SDL_CDOpen(int drive) break; /* max tracks you can have on an audio CD. */ } } - if (retval->numtracks == 1 && retval->track[0].type != 0) { + if (!has_audio) { retval->numtracks = 0; /* data-only */ } SDL20_free(mp3); From a2da9172b6666cb4dedced3807a093b5893e58a6 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 31 Aug 2022 00:24:37 -0400 Subject: [PATCH 297/606] FIXME removal: this was just fixed this in the last commit. Reference Issue #143. --- src/SDL12_compat.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 6b5e22470..e7265730c 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -8351,8 +8351,6 @@ SDL_CDOpen(int drive) int c; char c0, c1; - /* we only report audio tracks, starting at 1... */ - FIXME("Let there be fake data tracks"); c = retval->numtracks + 1; c0 = c / 10 + '0'; c1 = c % 10 + '0'; From 8d1966f4b7e4ec3af9ef9168d45b705f5768678c Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 1 Sep 2022 00:05:39 -0400 Subject: [PATCH 298/606] audio: Fail a little more gracefully on audio device reopen failure. Reference Issue #143. --- src/SDL12_compat.c | 38 +++++++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index e7265730c..657de4023 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -8908,6 +8908,7 @@ OpenSDL2AudioDevice(SDL_AudioSpec *want) { void (SDLCALL *orig_callback)(void *userdata, Uint8 *stream, int len) = want->callback; void *orig_userdata = want->userdata; + AudioCallbackWrapperData *allocated_cbdata = NULL; int retval; /* Two things use the audio device: the app, through 1.2's SDL_OpenAudio, @@ -8928,17 +8929,35 @@ OpenSDL2AudioDevice(SDL_AudioSpec *want) return SDL_TRUE; } } else { - audio_cbdata = (AudioCallbackWrapperData *) SDL20_calloc(1, sizeof (AudioCallbackWrapperData)); + allocated_cbdata = audio_cbdata = (AudioCallbackWrapperData *) SDL20_calloc(1, sizeof (AudioCallbackWrapperData)); if (!audio_cbdata) { SDL20_OutOfMemory(); return SDL_FALSE; } } - FIXME("if this fails, we need to deal with app callback or cd-rom no longer working"); want->callback = AudioCallbackWrapper; want->userdata = audio_cbdata; retval = (SDL20_OpenAudio(want, &audio_cbdata->device_format) == 0); + if (retval == -1) { + if (audio_cbdata->app_callback_opened || audio_cbdata->cdrom_opened) { + SDL20_Log("sdl12-compat: Uhoh, reopening the SDL2 audio device failed: %s", SDL20_GetError()); + if (audio_cbdata->app_callback_opened) { + /* we aren't going to bother to fake the audio callback for this case. */ + SDL20_Log("sdl12-compat: More audio won't play and app might crash!"); + } + if (audio_cbdata->cdrom_opened) { + SDL20_Log("sdl12-compat: CD-ROM audio will stop now!"); + audio_cbdata->cdrom_status = SDL12_CD_TRAYEMPTY; + } + } + if (allocated_cbdata) { + audio_cbdata = NULL; + SDL_free(allocated_cbdata); + } + return SDL_FALSE; + } + want->callback = orig_callback; want->userdata = orig_userdata; want->size = want->samples * want->channels * (SDL_AUDIO_BITSIZE(want->format) / 8); @@ -8947,9 +8966,18 @@ OpenSDL2AudioDevice(SDL_AudioSpec *want) want->silence = SDL_AUDIO_ISSIGNED(want->format) ? 0x00 : 0x80; /* reset audiostreams if device format changed. */ - FIXME("deal with failure in here"); - ResetAudioStreamForDeviceChange(&audio_cbdata->app_callback_stream, &audio_cbdata->app_callback_format); - ResetAudioStreamForDeviceChange(&audio_cbdata->cdrom_stream, &audio_cbdata->cdrom_format); + if (!ResetAudioStreamForDeviceChange(&audio_cbdata->app_callback_stream, &audio_cbdata->app_callback_format)) { + SDL20_Log("sdl12-compat: Uhoh, failed to prepare audio stream for audio device reopen: %s", SDL20_GetError()); + SDL20_Log("sdl12-compat: More audio won't play and app might crash!"); + audio_cbdata->app_callback_opened = SDL_FALSE; + } + + if (!ResetAudioStreamForDeviceChange(&audio_cbdata->cdrom_stream, &audio_cbdata->cdrom_format)) { + SDL20_Log("sdl12-compat: Uhoh, failed to prepare audio stream for audio device reopen: %s", SDL20_GetError()); + SDL20_Log("sdl12-compat: CD-ROM audio will stop now!"); + audio_cbdata->cdrom_opened = SDL_FALSE; + audio_cbdata->cdrom_status = SDL12_CD_TRAYEMPTY; + } SDL20_LockAudio(); SDL20_PauseAudio(0); /* always unpause, but caller will unlock after finalizing setup. */ From af3155aa7569c846b79df6929a9a2326ae3572fc Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 1 Sep 2022 00:08:13 -0400 Subject: [PATCH 299/606] FIXME removal: Added a conditional `#warning` for the unimplemented path. --- src/SDL12_compat.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 657de4023..7dcc6ba1f 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1235,7 +1235,8 @@ static void OS_GetExeName(char *buf, const unsigned maxpath) { buf[0] = '\0'; DosQueryModuleName(pib->pib_hmte, maxpath, buf); } -#else /* FIXME */ +#else +#warning Please implement this for your platform. static void OS_GetExeName(char *buf, const unsigned maxpath) { buf[0] = '\0'; (void)maxpath; From 7e4b00fe413a29529680b0ee4c042293a9e4823a Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 1 Sep 2022 00:08:36 -0400 Subject: [PATCH 300/606] FIXME removal: remove the ENABLE_FIXMES code. We're out of FIXMEs! Now that sdl12-compat is no longer running in a it-sorta-runs-but-warn-me-about-compatibility-gaps mode, and we're pretty confident that this is a solid compatibility layer, future FIXMEs will be basic comments and don't need a mechanism for spotlighting these sort of problems. Fixes #143. --- src/SDL12_compat.c | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 7dcc6ba1f..250f8e9de 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -80,30 +80,6 @@ extern "C" { #endif -#define ENABLE_FIXMES 1 -#if ENABLE_FIXMES == -1 /* don't even allow a build to finish if there's a FIXME */ - /* the goal with this nonsense is to make the compiler print an error that - broadcasts the problem _and the string literal_ from the actual FIXME line */ - extern void YouCannotBuildUntilYouResolveThisFixme(char *x); - #define FIXME(x) YouCannotBuildUntilYouResolveThisFixme(-->) -#elif ENABLE_FIXMES == 0 /* compile out any FIXMEs entirely. */ - #define FIXME(x) do {} while (0) -#elif ENABLE_FIXMES == 1 /* Log a warning the first time a FIXME is executed. */ - static SDL_bool PrintFixmes = SDL_TRUE; - #define FIXME(x) \ - do { \ - if (PrintFixmes) { \ - static SDL_bool seen = SDL_FALSE; \ - if (!seen) { \ - SDL20_Log("FIXME: %s (%s:%d)\n", x, __FUNCTION__, __LINE__); \ - seen = SDL_TRUE; \ - } \ - } \ - } while (0) -#else - #error Please fix the ENABLE_FIXMES define. -#endif - #define SDL20_SYM(rc,fn,params,args,ret) \ typedef rc (SDLCALL *SDL20_##fn##_t) params; \ static SDL20_##fn##_t SDL20_##fn = NULL; @@ -1359,9 +1335,6 @@ LoadSDL20(void) sprintf_fn(loaderror, "SDL2 %d.%d.%d library is too old.", v.major, v.minor, v.patch); } else { const SDL_bool debug_logging = SDL12Compat_GetHintBoolean("SDL12COMPAT_DEBUG_LOGGING", SDL_FALSE); - #if ENABLE_FIXMES == 1 - PrintFixmes = debug_logging; - #endif if (debug_logging) { #if defined(__DATE__) && defined(__TIME__) SDL20_Log("sdl12-compat, built on " __DATE__ " at " __TIME__ ", talking to SDL2 %d.%d.%d", v.major, v.minor, v.patch); From 11f38db3f652069a23a8835882fdef094b7cd224 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 1 Sep 2022 00:23:45 -0400 Subject: [PATCH 301/606] video: SDL_Flip shouldn't return an error for SDL_OPENGL surfaces. The same error message will get set (matching 1.2) when it calls down into SDL_UpdateRect(), but SDL_Flip still needs to return 0 in this case, to match 1.2 behavior. This should fix OpenXcom, which panics and terminates when it sees an error here. Fixes #185. --- src/SDL12_compat.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 250f8e9de..40cb62ea1 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -6585,10 +6585,6 @@ SDL_UpdateRect(SDL12_Surface *screen12, Sint32 x, Sint32 y, Uint32 w, Uint32 h) DECLSPEC int SDLCALL SDL_Flip(SDL12_Surface *surface12) { - if (surface12->flags & SDL12_OPENGL) { - return SDL20_SetError("Use SDL_GL_SwapBuffers() on OpenGL surfaces"); - } - if (surface12 == VideoSurface12) { SDL_UpdateRect(surface12, 0, 0, 0, 0); /* update the whole screen and present now. */ } From 183bac11d2060c68ace55c4396c951c97db4db81 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 1 Sep 2022 11:38:21 -0400 Subject: [PATCH 302/606] init: Better assertion check for init flags during SDL_Quit(). --- src/SDL12_compat.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 40cb62ea1..3956f8510 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -2488,13 +2488,14 @@ SDL_QuitSubSystem(Uint32 sdl12flags) } InitializedSubsystems20 &= ~sdl20flags; + InitializedSubsystems20 &= ~SDL_INIT_NOPARACHUTE; /* SDL2 accepts this flag but ignores it. */ } DECLSPEC void SDLCALL SDL_Quit(void) { SDL_QuitSubSystem(SDL_WasInit(0) | SDL12_INIT_CDROM); - SDL_assert(InitializedSubsystems20 == 0); + SDL_assert((InitializedSubsystems20 == 0) || (SDL12Compat_GetHintBoolean("SDL12COMPAT_NO_QUIT_VIDEO", SDL_FALSE) && (InitializedSubsystems20 == SDL_INIT_VIDEO))); } DECLSPEC void SDLCALL From 62c60ad9853a2a4af42553dcf05f6f4d000dff81 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 1 Sep 2022 11:39:02 -0400 Subject: [PATCH 303/606] quirks: Actually set the environment vars instead of using in GetHint. This way we can pass hints on to SDL2 instead of just using them inside sdl12-compat. --- src/SDL12_compat.c | 46 +++++++++++++--------------------------------- 1 file changed, 13 insertions(+), 33 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 3956f8510..2f5973df6 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1242,32 +1242,7 @@ SDL12Compat_GetExeName(void) static const char * SDL12Compat_GetHint(const char *name) { - const char *value; - const char *exe_name; - int i; - - /* First, check if there's an environment variable override. */ - value = SDL20_getenv(name); - if (value) { - return value; - } - - /* Else, look up the quirks table. */ - exe_name = SDL12Compat_GetExeName(); - if (*exe_name == '\0') { - return NULL; - } - - for (i = 0; i < SDL_arraysize(quirks); i++) { - if (!SDL20_strcmp(exe_name, quirks[i].exe_name)) { - if (!SDL20_strcmp(name, quirks[i].hint_name)) { - return quirks[i].hint_value; - } - } - } - - /* No value was found, NULL by default. */ - return NULL; + return SDL20_getenv(name); } static SDL_bool @@ -1295,10 +1270,11 @@ SDL12Compat_GetHintFloat(const char *name, float default_value) } static void -SDL12Compat_PrintQuirks(void) +SDL12Compat_ApplyQuirks(void) { - int i; + const SDL_bool debug_logging = SDL12Compat_GetHintBoolean("SDL12COMPAT_DEBUG_LOGGING", SDL_FALSE); const char *exe_name = SDL12Compat_GetExeName(); + int i; if (*exe_name == '\0') { return; @@ -1306,10 +1282,15 @@ SDL12Compat_PrintQuirks(void) for (i = 0; i < SDL_arraysize(quirks); i++) { if (!SDL20_strcmp(exe_name, quirks[i].exe_name)) { if (!SDL20_getenv(quirks[i].hint_name)) { - SDL20_Log("Applying compatibility quirk %s=\"%s\" for \"%s\"", quirks[i].hint_name, quirks[i].hint_value, exe_name); + if (debug_logging) { + SDL20_Log("Applying compatibility quirk %s=\"%s\" for \"%s\"", quirks[i].hint_name, quirks[i].hint_value, exe_name); + } + SDL20_setenv(quirks[i].hint_name, quirks[i].hint_value, 1); } else { - SDL20_Log("Not applying compatibility quirk %s=\"%s\" for \"%s\" due to environment variable override (\"%s\")\n", - quirks[i].hint_name, quirks[i].hint_value, exe_name, SDL20_getenv(quirks[i].hint_name)); + if (debug_logging) { + SDL20_Log("Not applying compatibility quirk %s=\"%s\" for \"%s\" due to environment variable override (\"%s\")\n", + quirks[i].hint_name, quirks[i].hint_value, exe_name, SDL20_getenv(quirks[i].hint_name)); + } } } } @@ -1341,8 +1322,7 @@ LoadSDL20(void) #else SDL20_Log("sdl12-compat, talking to SDL2 %d.%d.%d", v.major, v.minor, v.patch); #endif - /* Print a list of any enabled quirks. */ - SDL12Compat_PrintQuirks(); + SDL12Compat_ApplyQuirks(); /* Apply and maybe print a list of any enabled quirks. */ } } } From e511d82c9f5f5b20eb3ccb7c7f37b5007a073a23 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 1 Sep 2022 11:42:44 -0400 Subject: [PATCH 304/606] quirks: Force "tucnak" to x11, software renderer, and no framebuffer texture. It uses rendering and the event loop from different threads, so it upsets OpenGL and is hard to work around, beyond just falling back to an all-software rendering path (which means it has to use X11 too). There is a real SDL2 target for this app, which doesn't have these limitations, but this gets the SDL 1.2 target working. Fixes #182. --- COMPATIBILITY.md | 13 +++++++++++++ src/SDL12_compat.c | 7 +++++++ 2 files changed, 20 insertions(+) diff --git a/COMPATIBILITY.md b/COMPATIBILITY.md index b8796216d..c0994cd67 100644 --- a/COMPATIBILITY.md +++ b/COMPATIBILITY.md @@ -47,3 +47,16 @@ directly, so this does not prevent the game from working on Wayland. No XWayland needed! +## Tucnak (Linux) + +There is an SDL2 target for libzia (which tucnak uses for rendering), and you +should use that in modern times. But if you're on the SDL 1.2 target, +tucnak tries to render from a background thread, and does its event loop on +another, so we can't cleanly hook in to make it draw from the main thread. + +sdl12-compat will force SDL2 to use X11, software rendering, and no texture +framebuffer, to avoid using OpenGL, to avoid the threading problems this +will cause. The app is perfectly usable in this configuration (and largely +matches how they expected you to use it with SDL 1.2 anyhow). + + diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 2f5973df6..bb015e5a7 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1184,6 +1184,13 @@ static QuirkEntryType quirks[] = { {"dosbox_i686", "SDL12COMPAT_USE_KEYBOARD_LAYOUT", "0"}, {"dosbox_x86_64", "SDL12COMPAT_USE_KEYBOARD_LAYOUT", "0"}, + /* Tucnak's 1.2 target wants to render and run its event loop from + background threads, which upsets OpenGL. Force software renderer and + x11. If you want Wayland, etc, use tuknak's existing SDL2 target. */ + {"tucnak", "SDL_VIDEODRIVER", "x11"}, + {"tucnak", "SDL_RENDER_DRIVER", "software"}, + {"tucnak", "SDL_FRAMEBUFFER_ACCELERATION", "false"}, + /* The 32-bit Steam build only of Multiwinia Quits but doesn't re-Init */ {"multiwinia.bin.x86", "SDL12COMPAT_NO_QUIT_VIDEO", "1"} #else From 5642d47ae489f2eb362cece2464ecc466a700ed5 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 1 Sep 2022 11:57:59 -0400 Subject: [PATCH 305/606] cmake: remove blank INSTALL_NAME_DIR property on Apple targets. It apparently didn't fix the thing it was trying to fix, and it's causing other problems. Fixes #194. --- CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 70cdb5a33..aa40e3616 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -74,7 +74,6 @@ if(UNIX AND NOT APPLE) target_link_libraries(SDL PRIVATE ${CMAKE_DL_LIBS}) endif() if(APPLE) - set_target_properties(SDL PROPERTIES INSTALL_NAME_DIR "") set_target_properties(SDL PROPERTIES COMPILE_DEFINITIONS "_THREAD_SAFE") set_target_properties(SDL PROPERTIES LINK_FLAGS "-Wl,-compatibility_version,${DYLIB_COMPAT_VERSION} -Wl,-current_version,${DYLIB_CURRENT_VERSION}") From aa87f014c1240cc6f518f8b072f84a0f8e06e95c Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 1 Sep 2022 14:47:25 -0400 Subject: [PATCH 306/606] video: Try to reset current GL context after touching the renderer. This way if an app tries to render on a background thread, SDL2's GL renderers will have a chance of working, since they'll be able to set the context current for that thread. This does not fix tucnak, for reasons that aren't clear, so that'll continue to force the software renderer through the quirks mechanism, but it definitely seems to fix linapple and probably other things, too. Fixes #104. Fixes #110. Fixes #181. Fixes #155. (I think.) --- src/SDL12_compat.c | 31 +++++++++++++++++++++++++++++++ src/SDL20_syms.h | 1 + 2 files changed, 32 insertions(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index bb015e5a7..d89a5b125 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -5578,6 +5578,26 @@ InitializeOpenGLScaling(const int w, const int h) } +/* The idea here is that SDL's OpenGL-based renderers always notice if + they aren't using the correct context and attempt to set the correct + context before doing any work, but (at least for X11, and probably + other platforms), the current context is thread-local, and _it's an + error to set a context current if it's already current on another thread_. + So we try to catch every place we call into the renderer and end that + work with a call to this function, which will reset the GL context to NULL, + so if an app tries to render from a background thread, the GL renderer + will be able to set the context, do it's work, and then we reset it right + after. Without this, we either need all apps to render exclusively on + the main thread or fail to draw at all. + + This feels risky, but it's better than the alternative! */ +static void ResetVideoRendererForThreading(void) +{ + if ((VideoRenderer20 != NULL) && (SDL20_GL_GetCurrentContext() != NULL)) { + SDL20_GL_MakeCurrent(NULL, NULL); + } +} + static void HandleInputGrab(SDL12_GrabMode mode); DECLSPEC SDL12_Surface * SDLCALL @@ -6008,6 +6028,10 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12) VideoSurfacePresentTicks = 0; VideoSurfaceLastPresentTicks = 0; + if ((flags12 & SDL12_OPENGL) == 0) { + ResetVideoRendererForThreading(); + } + return VideoSurface12; } @@ -6322,6 +6346,8 @@ PresentScreen(void) SDL20_RenderPresent(VideoRenderer20); VideoSurfaceLastPresentTicks = SDL20_GetTicks(); VideoSurfacePresentTicks = 0; + + ResetVideoRendererForThreading(); } static void @@ -6752,6 +6778,7 @@ SDL_WM_ToggleFullScreen(SDL12_Surface *surface) } if (retval && VideoRenderer20) { SDL20_RenderSetLogicalSize(VideoRenderer20, VideoSurface12->w, VideoSurface12->h); + ResetVideoRendererForThreading(); } } return retval; @@ -7203,6 +7230,8 @@ SDL_CreateYUVOverlay(int w, int h, Uint32 format12, SDL12_Surface *display12) retval->pixels = hwdata->pixels; hwdata->dirty = SDL_TRUE; + ResetVideoRendererForThreading(); + return retval; } @@ -7298,6 +7327,8 @@ SDL_DisplayYUVOverlay(SDL12_Overlay *overlay12, SDL12_Rect *dstrect12) VideoSurfacePresentTicks = VideoSurfaceLastPresentTicks + GetDesiredMillisecondsPerFrame(); /* flip it later. */ } + ResetVideoRendererForThreading(); + return 0; } diff --git a/src/SDL20_syms.h b/src/SDL20_syms.h index b4b7d04fc..8c4bf0afa 100644 --- a/src/SDL20_syms.h +++ b/src/SDL20_syms.h @@ -136,6 +136,7 @@ SDL20_SYM(int,GL_GetAttribute,(SDL_GLattr a, int *b),(a,b),return) SDL20_SYM(int,GL_SetSwapInterval,(int a),(a),return) SDL20_SYM(int,GL_GetSwapInterval,(void),(),return) SDL20_SYM(SDL_GLContext,GL_CreateContext,(SDL_Window *a),(a),return) +SDL20_SYM(SDL_GLContext,GL_GetCurrentContext,(void),(),return) SDL20_SYM(int,GL_MakeCurrent,(SDL_Window *a, SDL_GLContext b),(a,b),return) SDL20_SYM(void,GL_SwapWindow,(SDL_Window *a),(a),) SDL20_SYM(void,GL_DeleteContext,(SDL_GLContext a),(a),) From e8ef34f52c14000984feb3164af07743da14ee69 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 1 Sep 2022 16:05:34 -0400 Subject: [PATCH 307/606] COMPATIBILITY.md: Make a note about Dynamic Jack's binary name. It's "main" ...! We can't reasonably add that to the quirks table. :( Fixes #198. --- COMPATIBILITY.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/COMPATIBILITY.md b/COMPATIBILITY.md index c0994cd67..2cc1447f4 100644 --- a/COMPATIBILITY.md +++ b/COMPATIBILITY.md @@ -20,6 +20,10 @@ on X11 if you turn off OpenGL Scaling Note that this game calls glXGetProcAddress() directly and likely will not work as a native Wayland app (XWayland works fine, however). +You have to set this environment variable yourself. Dynamic Jack's binary +is called "main" so we can't reasonably set up an automatic entry for it in +our quirks table. + ## Hammerfight (Linux) From 6282982bb2387c290d106e0401c5b16093565618 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 1 Sep 2022 16:15:24 -0400 Subject: [PATCH 308/606] COMPATIBILITY.md: added notes about several apps. Fixes #197. --- COMPATIBILITY.md | 47 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/COMPATIBILITY.md b/COMPATIBILITY.md index 2cc1447f4..41e59d67d 100644 --- a/COMPATIBILITY.md +++ b/COMPATIBILITY.md @@ -13,7 +13,7 @@ https://docs.google.com/spreadsheets/d/1u8Rq3LVQYYgu28sBuxrZ371QolbiZu5z_LjENc4d ## Dynamite Jack (Linux) More modern builds are ported to SDL2, but the older 1.2 binaries will work -on X11 if you turn off OpenGL Scaling +on X11 if you turn off OpenGL Scaling. export SDL12COMPAT_OPENGL_SCALING=0 @@ -64,3 +64,48 @@ will cause. The app is perfectly usable in this configuration (and largely matches how they expected you to use it with SDL 1.2 anyhow). +## Awesomenauts (Linux) + +Awesomenauts requires X11 because it talks directly to glX, can't use our +scaling code because it uses framebuffer objects without going through +SDL_GL_GetProcAddress() to get entry points, and does something weird with +OpenGL contexts on multiple threads. sdl12-compat detects this and forces +on the correct hints to make this work, but it limits how one can use the +game. + +This game will work in a Wayland environment, but only as an X11 app through +XWayland. + + +## Braid (Linux) + +Braid requires X11 because it talks directly to glX, and can't use our +scaling code because it uses framebuffer objects without going through +SDL_GL_GetProcAddress() to get entry points. sdl12-compat detects this +and forces on the correct hints to make this work, but it limits how +one can use the game. + +This game will work in a Wayland environment, but only as an X11 app through +XWayland. + + +## DOSBox (Linux) + +DOSBox has some pretty strict requirements for keyboard input. We detect +some common names for DOSBox binaries ("dosbox", "dosbox_i686", etc), and +force the correct hints to make it work, but if you have an uncommon binary +name and keyboard input isn't working as you expect, try exporting this +environment variable: + + export SDL12COMPAT_USE_KEYBOARD_LAYOUT=0 + + +## Multiwinia (Linux) + +Multiwinia calls SDL_Quit() when changing video modes but doesn't +reinitialize SDL before using it further. We detect this binary and force +the correct hints to make it work, but if you have an uncommon binary +name and the game isn't working, try this environment variable: + + export SDL12COMPAT_NO_QUIT_VIDEO=1 + From d764cc68f81228ccb6d864b7bc7d0a4ce66bfccd Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 1 Sep 2022 19:12:15 -0400 Subject: [PATCH 309/606] README.md: Note that environment variables are not to be modified. Fixes #188. --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index f6f489fbc..2c120bf93 100644 --- a/README.md +++ b/README.md @@ -144,6 +144,13 @@ SDL12COMPAT_HIGHDPI=1 SDL12COMPAT_OPENGL_SCALING=0 %command% will run `%command%` with high-dpi monitor support enabled, but OpenGL scaling support disabled. +(While these environment variables are checked at various times throughout +the lifetime of the app, sdl12-compat expects these to be set before the +process starts and not change during the life of the process, and any +places where changing it later might affect operation is purely accidental +and might change. That is to say: don't write an SDL 1.2-based app with +plans to tweak these values on the fly!) + The available options are: - SDL12COMPAT_DEBUG_LOGGING: From 3dfc526095ae3bd245529f8925dc326777902340 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 1 Sep 2022 19:15:55 -0400 Subject: [PATCH 310/606] LICENSE.txt: Updated copyright for 2022. --- LICENSE.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE.txt b/LICENSE.txt index 04694607b..a41260a29 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,4 +1,4 @@ -Copyright (C) 1997-2021 Sam Lantinga +Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages From 82d2aef7f063e24d2d1f41c763072dc1fa6d0663 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 1 Sep 2022 19:19:49 -0400 Subject: [PATCH 311/606] Changed BUGS.txt to Markdown, plus minor tweaks. --- BUGS.md | 20 ++++++++++++++++++++ BUGS.txt | 18 ------------------ 2 files changed, 20 insertions(+), 18 deletions(-) create mode 100644 BUGS.md delete mode 100644 BUGS.txt diff --git a/BUGS.md b/BUGS.md new file mode 100644 index 000000000..26159a8e8 --- /dev/null +++ b/BUGS.md @@ -0,0 +1,20 @@ + +# Reporting bugs + +Bugs are now managed in sdl12-compat's GitHub Issues tracker: + +https://github.com/libsdl-org/sdl12-compat/issues + +You may report bugs there, and search to see if a given issue has already +been reported, discussed, and maybe even fixed. + + +# Discussion with other humans + +You may also find help at the SDL forums: + +https://discourse.libsdl.org/ + +Bug reports are welcome here, but we really appreciate if you use the bug +tracker, as bugs discussed on the forums may be forgotten or missed. + diff --git a/BUGS.txt b/BUGS.txt deleted file mode 100644 index 2e31b0ba0..000000000 --- a/BUGS.txt +++ /dev/null @@ -1,18 +0,0 @@ - -Bugs are now managed in GitHub Issues, here: - - https://github.com/libsdl-org/sdl12-compat/issues - -You may report bugs there, and search to see if a given issue has already - been reported, discussed, and maybe even fixed. - - - -You may also find help at the SDL forums: - - https://discourse.libsdl.org/ - -Bug reports are welcome here, but we really appreciate if you use the bug - tracker, as bugs discussed on the forums may be forgotten or missed. - - From 64f8aa8834c2bd5d64d473aba34d16021df3975b Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 1 Sep 2022 19:23:49 -0400 Subject: [PATCH 312/606] COMPATIBILITY.md: Minor edits to Hammerfight info. --- COMPATIBILITY.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/COMPATIBILITY.md b/COMPATIBILITY.md index 41e59d67d..e99ba6b64 100644 --- a/COMPATIBILITY.md +++ b/COMPATIBILITY.md @@ -30,8 +30,9 @@ our quirks table. You probably aren't getting usable mouse input, as the game talks directly to XInput2 on X11 (and tries to use /dev/input if that fails). This is not an sdl12-compat bug, as this is going outside of SDL to get multiple mice -input. The game is statically linked to a copy of [ManyMouse](https://icculus.org/manymouse/), -which provides multiple mice access. +input. The game is statically linked to a copy of +[ManyMouse](https://icculus.org/manymouse/), which provides multiple mice +access. The simplest way to deal with this is change this line in the game's @@ -39,14 +40,14 @@ Config.ini file: CORE_INIT_RI=true -Make that false and it won't even try to initialize ManyMouse, and will use +Make that `false` and it won't even try to initialize ManyMouse, and will use standard SDL 1.2 mouse events for single-player input. (The "RI" stands for "RawInput," which Hammerfight uses on Windows for multi-mice support). Of course, with this change, you can't have multiple players on the same machine using separate mice. -That game dlopen()'s the XInput2 libraries instead of linking to them +Hammerfight dlopen()'s the XInput2 libraries instead of linking to them directly, so this does not prevent the game from working on Wayland. No XWayland needed! From 56119b273d54fcf91805b0026ddacf4a978335f2 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 1 Sep 2022 19:59:33 -0400 Subject: [PATCH 313/606] video: Apparently 24-bit video is intended to be BGR24 pixels. We had changed this in 940352955ffef7ab4113bc28a2454a8f66b8e3f7, from RGB24 to RGB888, which fixed Schismtracker, but this isn't actually correct either, I guess. Using BGR24 fixes "Powder", which apparently _needs_ a 24-bit packed format, and Schismtracker still works correctly, so I think we're good here now. I hope. Fixes #199. --- src/SDL12_compat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index d89a5b125..fa53b6758 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -5693,7 +5693,7 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12) switch (bpp) { case 8: appfmt = SDL_PIXELFORMAT_INDEX8; break; case 16: appfmt = SDL_PIXELFORMAT_RGB565; break; - case 24: appfmt = SDL_PIXELFORMAT_RGB888; break; + case 24: appfmt = SDL_PIXELFORMAT_BGR24; break; case 32: appfmt = SDL_PIXELFORMAT_XRGB8888; break; default: SDL20_SetError("Unsupported bits-per-pixel"); return NULL; } From 16609a08b62abd4d6e76d552f45960a6981f3353 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 2 Sep 2022 11:29:15 -0400 Subject: [PATCH 314/606] audio: Always open the audio device at at least CD audio quality. We have to be prepared to convert/buffer between the app's wants and SDL2's anyhow, and this lets us make sure that if the app tries to play a CD after opening audio at a low quality, we don't have to reopen the SDL2 audio device to accomodate it. Fixes #202. --- src/SDL12_compat.c | 121 +++++++++++++++++---------------------------- 1 file changed, 44 insertions(+), 77 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index fa53b6758..996e9c767 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -8165,7 +8165,7 @@ mp3_sdlrwops_seek(void *data, int offset, drmp3_seek_origin origin) } -static int OpenSDL2AudioDevice(SDL_AudioSpec *); +static SDL_bool OpenSDL2AudioDevice(SDL_AudioSpec *want); static int CloseSDL2AudioDevice(void); static SDL_bool ResetAudioStream(SDL_AudioStream **_stream, SDL_AudioSpec *spec, const SDL_AudioSpec *to, const SDL_AudioFormat fromfmt, const Uint8 fromchannels, const int fromfreq); @@ -8882,96 +8882,63 @@ ResetAudioStream(SDL_AudioStream **_stream, SDL_AudioSpec *spec, const SDL_Audio } static SDL_bool -ResetAudioStreamForDeviceChange(SDL_AudioStream **_stream, SDL_AudioSpec *spec) +OpenSDL2AudioDevice(SDL_AudioSpec *appwant) { - if (*_stream == NULL) { - return SDL_TRUE; /* no stream, no need to reset it. */ - } - SDL20_FreeAudioStream(*_stream); /* force it to rebuild because destination format changed. */ - *_stream = NULL; - return ResetAudioStream(_stream, spec, &audio_cbdata->device_format, spec->format, spec->channels, spec->freq); -} + SDL_AudioSpec devwant; -static int -OpenSDL2AudioDevice(SDL_AudioSpec *want) -{ - void (SDLCALL *orig_callback)(void *userdata, Uint8 *stream, int len) = want->callback; - void *orig_userdata = want->userdata; - AudioCallbackWrapperData *allocated_cbdata = NULL; - int retval; + /* note that 0x80 isn't perfect silence for U16 formats, but we only have one byte that is used for memset() calls, so it has to do. SDL2 has the same bug. */ + appwant->silence = SDL_AUDIO_ISSIGNED(appwant->format) ? 0x00 : 0x80; + appwant->size = appwant->samples * appwant->channels * (SDL_AUDIO_BITSIZE(appwant->format) / 8); - /* Two things use the audio device: the app, through 1.2's SDL_OpenAudio, - and the fake CD-ROM device. Either can open the device, and both write - to SDL_AudioStreams to buffer and convert data. We try to open the device - in a format that accommodates both inputs, but we might close the device - and reopen it if we need more channels, etc. */ if (audio_cbdata != NULL) { /* device is already open. */ - SDL_AudioSpec *have = &audio_cbdata->device_format; - if ( (want->freq > have->freq) || - (want->channels > have->channels) || - (want->samples > have->samples) || - (SDL_AUDIO_ISFLOAT(want->format) && !SDL_AUDIO_ISFLOAT(have->format)) || - (SDL_AUDIO_BITSIZE(want->format) > SDL_AUDIO_BITSIZE(have->format)) ) { - SDL20_CloseAudio(); - } else { - SDL20_LockAudio(); /* Device is already at acceptable parameters, just pause it for further setup by caller. */ - return SDL_TRUE; - } - } else { - allocated_cbdata = audio_cbdata = (AudioCallbackWrapperData *) SDL20_calloc(1, sizeof (AudioCallbackWrapperData)); - if (!audio_cbdata) { - SDL20_OutOfMemory(); - return SDL_FALSE; - } + SDL20_LockAudio(); /* Device is already at acceptable parameters, just pause it for further setup by caller. */ + return SDL_TRUE; } - want->callback = AudioCallbackWrapper; - want->userdata = audio_cbdata; - retval = (SDL20_OpenAudio(want, &audio_cbdata->device_format) == 0); - if (retval == -1) { - if (audio_cbdata->app_callback_opened || audio_cbdata->cdrom_opened) { - SDL20_Log("sdl12-compat: Uhoh, reopening the SDL2 audio device failed: %s", SDL20_GetError()); - if (audio_cbdata->app_callback_opened) { - /* we aren't going to bother to fake the audio callback for this case. */ - SDL20_Log("sdl12-compat: More audio won't play and app might crash!"); - } - if (audio_cbdata->cdrom_opened) { - SDL20_Log("sdl12-compat: CD-ROM audio will stop now!"); - audio_cbdata->cdrom_status = SDL12_CD_TRAYEMPTY; - } - } - if (allocated_cbdata) { - audio_cbdata = NULL; - SDL_free(allocated_cbdata); - } + audio_cbdata = (AudioCallbackWrapperData *) SDL20_calloc(1, sizeof (AudioCallbackWrapperData)); + if (!audio_cbdata) { + SDL20_OutOfMemory(); return SDL_FALSE; } - want->callback = orig_callback; - want->userdata = orig_userdata; - want->size = want->samples * want->channels * (SDL_AUDIO_BITSIZE(want->format) / 8); - - /* note that 0x80 isn't perfect silence for U16 formats, but we only have one byte that is used for memset() calls, so it has to do. SDL2 has the same bug. */ - want->silence = SDL_AUDIO_ISSIGNED(want->format) ? 0x00 : 0x80; - - /* reset audiostreams if device format changed. */ - if (!ResetAudioStreamForDeviceChange(&audio_cbdata->app_callback_stream, &audio_cbdata->app_callback_format)) { - SDL20_Log("sdl12-compat: Uhoh, failed to prepare audio stream for audio device reopen: %s", SDL20_GetError()); - SDL20_Log("sdl12-compat: More audio won't play and app might crash!"); - audio_cbdata->app_callback_opened = SDL_FALSE; - } - - if (!ResetAudioStreamForDeviceChange(&audio_cbdata->cdrom_stream, &audio_cbdata->cdrom_format)) { - SDL20_Log("sdl12-compat: Uhoh, failed to prepare audio stream for audio device reopen: %s", SDL20_GetError()); - SDL20_Log("sdl12-compat: CD-ROM audio will stop now!"); - audio_cbdata->cdrom_opened = SDL_FALSE; - audio_cbdata->cdrom_status = SDL12_CD_TRAYEMPTY; + /* Two things use the audio device: the app, through 1.2's SDL_OpenAudio, + and the fake CD-ROM device. Either can open the device, and both write + to SDL_AudioStreams to buffer and convert data. We open the device + in a format that accommodates both inputs. + + In case the app asks for something really low-quality--an old game + playing 8-bit mono audio at 8000Hz or whatever--we force the audio + hardware to something better, in case the app _also_ wants to play + CD audio, so we can get good quality out of that without reopening + the device. We have to be able to buffer and convert between the + app's needs and SDL2's anyhow, so this isn't a big deal. If they + ask for better than CD quality, we'll allow it and upsample any + CD audio that is played. + + If the CD-ROM is opened first, and the app wants better-than-CD + quality later, there's not much we can do, it'll have to + downsample, but I suspect this is rare, and the audio will + still be good enough. */ + + SDL20_memcpy(&devwant, appwant, sizeof (SDL_AudioSpec)); + devwant.callback = AudioCallbackWrapper; + devwant.userdata = audio_cbdata; + devwant.freq = SDL_max(devwant.freq, 44100); + devwant.channels = SDL_max(devwant.channels, 2); + if (SDL_AUDIO_BITSIZE(devwant.format) < 16) { + devwant.format = AUDIO_S16SYS; + } + + if (SDL20_OpenAudio(&devwant, &audio_cbdata->device_format) == -1) { + SDL_free(audio_cbdata); + audio_cbdata = NULL; + return SDL_FALSE; } SDL20_LockAudio(); SDL20_PauseAudio(0); /* always unpause, but caller will unlock after finalizing setup. */ - return retval; + return SDL_TRUE; } static int From 829a8537348fb2c78ba826507187d705322c1fe7 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 2 Sep 2022 12:26:16 -0400 Subject: [PATCH 315/606] HOW_TO_TEST_GAMES.md: Added some notes to help you get started! --- HOW_TO_TEST_GAMES.md | 148 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 HOW_TO_TEST_GAMES.md diff --git a/HOW_TO_TEST_GAMES.md b/HOW_TO_TEST_GAMES.md new file mode 100644 index 000000000..9b399332e --- /dev/null +++ b/HOW_TO_TEST_GAMES.md @@ -0,0 +1,148 @@ +# Testing games with sdl12-compat + +sdl12-compat is here to make sure older games not only work well, but work +_correctly_, and for that, we need an army of testers. + +Here's how to test games with sdl12-compat. + + +## The general idea + +- Build [SDL2](https://github.com/libsdl-org/SDL) or find a prebuilt binary. +- Build sdl12-compat (documentation is in README.md) +- Find a game to test. +- Make sure a game uses sdl12-compat instead of classic SDL 1.2 +- See if game works or blows up, report back. + + +## Find a game to test + +We are keeping a spreadsheet of known games that still use SDL 1.2 +[here](https://docs.google.com/spreadsheets/d/1u8Rq3LVQYYgu28sBuxrZ371QolbiZu5z_LjENc4ddZs/edit?usp=sharing). + +Find something that hasn't been tested, or hasn't been tested recently, and +give it a try! Then update the spreadsheet. + +Extra credit if you [file bug reports](https://github.com/libsdl-org/sdl12-compat/issues) +but we're grateful if you just make notes on the spreadsheet, too. + + +## Make sure the game works with real SDL 1.2 first! + +You'd be surprised how many games have bitrotted! If it doesn't work with +real 1.2 anymore, it's not a bug if sdl12-compat doesn't work either. That +being said, lots of games that stopped working _because_ of SDL 1.2 will +now work again with sdl12-compat, which is nice, but just make sure you have +a baseline before you start testing. + + +## Force it to use sdl12-compat instead. + +Either overwrite the copy of SDL-1.2 that the game uses with sdl12-compat, +or (on Linux) export LD_LIBRARY_PATH to point to your copy, so the system will +favor it when loading libraries. + + +## Am I actually running sdl12-compat? + +The easiest way to know is to set some environment variables: + +```bash +export SDL12COMPAT_DEBUG_LOGGING=1 +``` + +If this is set, when loading sdl12-compat, it'll write something like this +to stderr (on Linux and Mac, at least)... + +``` +INFO: sdl12-compat, built on Sep 2 2022 at 11:27:37, talking to SDL2 2.25.0 +``` + +You can also use this: + +```bash +export SDL_EVENT_LOGGING=1 +``` + +Which will report every event SDL 2 sends to stderr: + +``` +INFO: SDL EVENT: SDL_WINDOWEVENT (timestamp=317 windowid=1 event=SDL_WINDOWEVENT_MOVED data1=1280 data2=674) +INFO: SDL EVENT: SDL_WINDOWEVENT (timestamp=318 windowid=1 event=SDL_WINDOWEVENT_EXPOSED data1=0 data2=0) +INFO: SDL EVENT: SDL_WINDOWEVENT (timestamp=318 windowid=1 event=SDL_WINDOWEVENT_ENTER data1=0 data2=0) +``` + +Since this is a new feature in SDL2, it'll only show up because sdl12-compat talks +to SDL2 and classic SDL 1.2 doesn't. + + +## Steam + +If testing a Steam game, you'll want to launch the game outside of the Steam +Client, so that Steam doesn't overwrite files you replaced and so you can +easily control environment variables. + +On Linux, Steam stores games in ~/.local/share/Steam/steamapps/common, each +in its own usually-well-named subdirectory. + +You'll want to add a file named "steam_appid.txt" to the same directory as +the binary, which will encourage Steamworks to _not_ terminate the process +and have the Steam Client relaunch it. This file should just have the appid +for the game in question, which you can find from the store page. + +For example, the store page for Braid is: + +https://store.steampowered.com/app/26800/Braid/ + +See that `26800`? That's the appid. + +```bash +echo 26800 > steam_appid.txt +``` + +For Linux, you can make sure that, from the command line, the game still +runs with the Steam Runtime and has the Steam Overlay by launching it with a +little script: + +- [steamapp32](https://raw.githubusercontent.com/icculus/twisty-little-utilities/main/steamapp32) for x86 binaries. +- [steamapp64](https://raw.githubusercontent.com/icculus/twisty-little-utilities/main/steamapp64) for x86-64 binaries. + +(And make sure you have a 32-bit or 64-bit build of sdl12-compat!) + +And then make sure you force it to use _your_ sdl12-compat instead of the +system/Steam Runtime build: + +```bash +export LD_LIBRARY_PATH=/where/i/installed/sdl12-compat +``` + +Putting this all together, you might run [BIT.TRIP Runner2](https://store.steampowered.com/app/218060/)\ +like this: + +```bash +cd ~/.local/share/Steam/steamapps/common/bittriprunner2 +export LD_LIBRARY_PATH=/where/i/installed/sdl12-compat +export SDL12COMPAT_DEBUG_LOGGING=1 +echo 218060 > steam_appid.txt +steamapp32 ./runner2 +``` + + +## Windows + +Generally, Windows games just ship with an SDL.dll, and you just need to +overwrite it with an sdl12-compat build, then run as usual. + + +## macOS, etc. + +(write me.) + + +## Questions? + +If something isn't clear, make a note [here](https://github.com/libsdl-org/sdl12-compat/issues/new) +and we'll update this document. + +Thanks! + From e2851419b764d7da6280120427a3455f0f44d205 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 2 Sep 2022 12:28:16 -0400 Subject: [PATCH 316/606] HOW_TO_TEST_GAMES.md: fixed typo. --- HOW_TO_TEST_GAMES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HOW_TO_TEST_GAMES.md b/HOW_TO_TEST_GAMES.md index 9b399332e..a32a43439 100644 --- a/HOW_TO_TEST_GAMES.md +++ b/HOW_TO_TEST_GAMES.md @@ -116,7 +116,7 @@ system/Steam Runtime build: export LD_LIBRARY_PATH=/where/i/installed/sdl12-compat ``` -Putting this all together, you might run [BIT.TRIP Runner2](https://store.steampowered.com/app/218060/)\ +Putting this all together, you might run [BIT.TRIP Runner2](https://store.steampowered.com/app/218060/) like this: ```bash From ae0fb29ed345253de396cee9c75b1285797742dd Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 2 Sep 2022 12:32:00 -0400 Subject: [PATCH 317/606] version: Bumping to 1.2.54 for release candidate. (Actual release will bump to 1.2.56, and then revision control will go to 1.2.57 for work, next release candidate will be 1.2.58, the 1.2.60, etc.) --- CMakeLists.txt | 4 ++-- src/Makefile.darwin | 2 +- src/Makefile.linux | 2 +- src/Makefile.os2 | 2 +- src/Makefile.w32 | 2 +- src/SDL12_compat.c | 2 +- src/version.rc | 8 ++++---- 7 files changed, 11 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index aa40e3616..ca88d6814 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.0.0) project(sdl12_compat - VERSION 1.2.53 + VERSION 1.2.54 LANGUAGES C) option(SDL12TESTS "Enable to build SDL-1.2 test programs" ON) @@ -22,7 +22,7 @@ if(APPLE) set_source_files_properties(${OSX_SRCS} PROPERTIES LANGUAGE C) # the following matches SDL-1.2 Xcode project file set(DYLIB_COMPAT_VERSION 1.0.0 CACHE STRING "library compatibility version") - set(DYLIB_CURRENT_VERSION 12.53.0 CACHE STRING "library current version") + set(DYLIB_CURRENT_VERSION 12.54.0 CACHE STRING "library current version") include_directories("/opt/X11/include") # hack. if(CMAKE_VERSION VERSION_LESS 3.9) else() diff --git a/src/Makefile.darwin b/src/Makefile.darwin index 7d4e81992..07e3caa94 100644 --- a/src/Makefile.darwin +++ b/src/Makefile.darwin @@ -18,7 +18,7 @@ CFLAGS = -mmacosx-version-min=10.6 -fPIC -O3 -Wall LDFLAGS = -mmacosx-version-min=10.6 -dynamiclib -Wl,-undefined,error -Wl,-single_module #LDFLAGS+= -Wl,-headerpad_max_install_names LDFLAGS+= -Wl,-install_name,"/usr/local/lib/$(DYLIB)" -LDFLAGS+= -Wl,-compatibility_version,1.0 -Wl,-current_version,12.53 +LDFLAGS+= -Wl,-compatibility_version,1.0 -Wl,-current_version,12.54 LDLIBS = -Wl,-framework,AppKit # this is needed for x86_64 - cross-gcc might not add it. #LDLIBS += -Wl,-lbundle1.o diff --git a/src/Makefile.linux b/src/Makefile.linux index def560386..2fecd5cdd 100644 --- a/src/Makefile.linux +++ b/src/Makefile.linux @@ -16,7 +16,7 @@ LDFLAGS = -shared -Wl,-soname,libSDL-1.2.so.0 LDFLAGS+= -Wl,--no-undefined LDLIBS = -ldl -SHLIB = libSDL-1.2.so.1.2.53 +SHLIB = libSDL-1.2.so.1.2.54 OBJ = SDL12_compat.o diff --git a/src/Makefile.os2 b/src/Makefile.os2 index 2d71d50d2..4f8a2ea1b 100644 --- a/src/Makefile.os2 +++ b/src/Makefile.os2 @@ -5,7 +5,7 @@ !endif DLLNAME = SDL12 -VERSION = 1.2.53 +VERSION = 1.2.54 # change SDL2INC to point to the SDL2 headers SDL2INC = include diff --git a/src/Makefile.w32 b/src/Makefile.w32 index 0585d17e5..adf54a867 100644 --- a/src/Makefile.w32 +++ b/src/Makefile.w32 @@ -5,7 +5,7 @@ !endif DLLNAME = SDL -VERSION = 1.2.53 +VERSION = 1.2.54 # change SDL2INC to point to the SDL2 headers SDL2INC = include diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 996e9c767..b893833e4 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -28,7 +28,7 @@ * should be way ahead of what SDL-1.2 Classic would report, so apps can * decide if they're running under the compat layer, if they really care. */ -#define SDL12_COMPAT_VERSION 53 +#define SDL12_COMPAT_VERSION 54 #include #include diff --git a/src/version.rc b/src/version.rc index 9bd5627f5..81cc8db0a 100644 --- a/src/version.rc +++ b/src/version.rc @@ -3,8 +3,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,2,53,0 - PRODUCTVERSION 1,2,53,0 + FILEVERSION 1,2,54,0 + PRODUCTVERSION 1,2,54,0 FILEFLAGSMASK 0x3fL FILEFLAGS 0x0L FILEOS 0x40004L @@ -17,12 +17,12 @@ BEGIN BEGIN VALUE "CompanyName", "\0" VALUE "FileDescription", "SDL\0" - VALUE "FileVersion", "1, 2, 53, 0\0" + VALUE "FileVersion", "1, 2, 54, 0\0" VALUE "InternalName", "SDL\0" VALUE "LegalCopyright", "Copyright © 2022 Sam Lantinga\0" VALUE "OriginalFilename", "SDL.dll\0" VALUE "ProductName", "Simple DirectMedia Layer 1.2 wrapper\0" - VALUE "ProductVersion", "1, 2, 53, 0\0" + VALUE "ProductVersion", "1, 2, 54, 0\0" END END BLOCK "VarFileInfo" From f689f8bcbf49f2be3e43dde2c54c865ffda6d326 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 2 Sep 2022 16:14:51 -0400 Subject: [PATCH 318/606] HOW_TO_TEST_GAMES: Note Steam Runtime has SDL2. --- HOW_TO_TEST_GAMES.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/HOW_TO_TEST_GAMES.md b/HOW_TO_TEST_GAMES.md index a32a43439..74c64b458 100644 --- a/HOW_TO_TEST_GAMES.md +++ b/HOW_TO_TEST_GAMES.md @@ -82,6 +82,9 @@ If testing a Steam game, you'll want to launch the game outside of the Steam Client, so that Steam doesn't overwrite files you replaced and so you can easily control environment variables. +Since you'll be using the Steam Runtime, you don't have to find your own copy +of SDL2, as Steam provides it. + On Linux, Steam stores games in ~/.local/share/Steam/steamapps/common, each in its own usually-well-named subdirectory. From 52da685446fa175877f24b776562c4875a41f44b Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Fri, 2 Sep 2022 23:40:00 +0300 Subject: [PATCH 319/606] includes: update version in SDL_version.h, too. --- include/SDL/SDL_version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/SDL/SDL_version.h b/include/SDL/SDL_version.h index 656556a80..a007e3f31 100644 --- a/include/SDL/SDL_version.h +++ b/include/SDL/SDL_version.h @@ -33,7 +33,7 @@ real SDL-1.2 available to you. */ /* We bumped the patchlevel to 50 for sdl12-compat */ #define SDL_MAJOR_VERSION 1 #define SDL_MINOR_VERSION 2 -#define SDL_PATCHLEVEL 50 +#define SDL_PATCHLEVEL 54 typedef struct SDL_version { From 6402c283983ada5e6f38dfc7e95085b3d343a841 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Fri, 2 Sep 2022 23:47:56 +0300 Subject: [PATCH 320/606] SDL_version.h: really update version. --- include/SDL/SDL_version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/SDL/SDL_version.h b/include/SDL/SDL_version.h index a007e3f31..46a29967c 100644 --- a/include/SDL/SDL_version.h +++ b/include/SDL/SDL_version.h @@ -45,7 +45,7 @@ typedef struct SDL_version #define SDL_VERSION(X) { \ (X)->major = 1; \ (X)->minor = 2; \ - (X)->patch = 50; \ + (X)->patch = 54; \ } #define SDL_VERSIONNUM(X, Y, Z) ((X)*1000 + (Y)*100 + (Z)) From e64bd40c92358afaa662e1c896d83003a8f60fba Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Fri, 2 Sep 2022 23:55:02 +0300 Subject: [PATCH 321/606] SDL_version.h: really, really update version. this header is cursed... (or I am...) --- include/SDL/SDL_version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/SDL/SDL_version.h b/include/SDL/SDL_version.h index 46a29967c..e25fe896f 100644 --- a/include/SDL/SDL_version.h +++ b/include/SDL/SDL_version.h @@ -49,7 +49,7 @@ typedef struct SDL_version } #define SDL_VERSIONNUM(X, Y, Z) ((X)*1000 + (Y)*100 + (Z)) -#define SDL_COMPILEDVERSION SDL_VERSIONNUM(1, 2, 50) +#define SDL_COMPILEDVERSION SDL_VERSIONNUM(1, 2, 54) #define SDL_VERSION_ATLEAST(X, Y, Z) (SDL_COMPILEDVERSION >= SDL_VERSIONNUM(X, Y, Z)) extern DECLSPEC const SDL_version * SDLCALL SDL_Linked_Version(void); From 7854b3c612e09e310362acd485892aee60b5e32e Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sat, 3 Sep 2022 01:28:00 +0300 Subject: [PATCH 322/606] restore compatibility with c++ compilers --- src/SDL12_compat.c | 10 +++++----- src/SDL20_syms.h | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index b893833e4..3755079ab 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1638,10 +1638,10 @@ Init12Joystick(void) if (JoysticksAreGameControllers) { JoystickList[NumJoysticks].dev.controller = SDL20_GameControllerOpen(i); - opened = JoystickList[NumJoysticks].dev.controller != NULL; + opened = JoystickList[NumJoysticks].dev.controller != NULL ? SDL_TRUE : SDL_FALSE; } else { JoystickList[NumJoysticks].dev.joystick = SDL20_JoystickOpen(i); - opened = JoystickList[NumJoysticks].dev.joystick != NULL; + opened = JoystickList[NumJoysticks].dev.joystick != NULL ? SDL_TRUE : SDL_FALSE; } if (!opened) { @@ -8331,7 +8331,7 @@ SDL_CDOpen(int drive) readdir() is surprisingly hard to do without a bunch of different platform backends! We just open files until we fail to do so, and then stop. */ - while (SDL_TRUE) { + for (;;) { SDL_RWops *rw; drmp3_uint64 pcmframes; drmp3_uint32 samplerate; @@ -8398,6 +8398,7 @@ SDL_CDOpen(int drive) break; /* max tracks you can have on an audio CD. */ } } + if (!has_audio) { retval->numtracks = 0; /* data-only */ } @@ -8983,8 +8984,7 @@ SDL_OpenAudio(SDL_AudioSpec *want, SDL_AudioSpec *obtained) if (!want->format) { const char *env = SDL20_getenv("SDL_AUDIO_FORMAT"); /* SDL 1.2 checks this. */ if (env != NULL) { - if (0) {} - else if (SDL20_strcmp(env, "U8") == 0) { want->format = AUDIO_U8; } + if (SDL20_strcmp(env, "U8") == 0) { want->format = AUDIO_U8; } else if (SDL20_strcmp(env, "S8") == 0) { want->format = AUDIO_S8; } else if (SDL20_strcmp(env, "U16") == 0) { want->format = AUDIO_U16SYS; } else if (SDL20_strcmp(env, "S16") == 0) { want->format = AUDIO_S16SYS; } diff --git a/src/SDL20_syms.h b/src/SDL20_syms.h index 8c4bf0afa..df76bfab9 100644 --- a/src/SDL20_syms.h +++ b/src/SDL20_syms.h @@ -240,8 +240,8 @@ SDL20_SYM(SDL_GameController *,GameControllerOpen,(int a),(a),return) SDL20_SYM(void,GameControllerClose,(SDL_GameController *a),(a),) SDL20_SYM(int,GameControllerEventState,(int a),(a),return) SDL20_SYM(void,GameControllerUpdate,(void),(),) -SDL20_SYM(Sint16,GameControllerGetAxis,(SDL_GameController *a, SDL_GameControllerAxis b),(a,b),return) -SDL20_SYM(Uint8,GameControllerGetButton,(SDL_GameController *a, SDL_GameControllerButton b),(a,b),return) +SDL20_SYM(Sint16,GameControllerGetAxis,(SDL_GameController *a, int b),(a,b),return) /* SDL_GameControllerAxis b */ +SDL20_SYM(Uint8,GameControllerGetButton,(SDL_GameController *a, int b),(a,b),return) /* SDL_GameControllerButton b */ SDL20_SYM(int,NumJoysticks,(void),(),return) SDL20_SYM(const char *,JoystickNameForIndex,(int a),(a),return) From 4d814ba89a6e87cd02e148d9d1504f77848e97dd Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sat, 3 Sep 2022 03:21:50 +0300 Subject: [PATCH 323/606] silence -Wsign-compare warnings. --- src/SDL12_compat.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 3755079ab..72d658275 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -988,7 +988,7 @@ static Uint8 EventStates[SDL12_NUMEVENTS]; static int SwapInterval = 0; static SDL_bool JoysticksAreGameControllers = SDL_FALSE; static SDL12_Joystick *JoystickList = NULL; -static Uint32 NumJoysticks = 0; +static int NumJoysticks = 0; static Uint8 KeyState[SDLK12_LAST]; static SDL_bool MouseInputIsRelative = SDL_FALSE; static SDL_Point MousePosition = { 0, 0 }; @@ -1092,7 +1092,7 @@ static char loaderror[256]; }; int i; - for (i = 0; i < SDL_arraysize(dylib_locations); i++) { + for (i = 0; i < (int) SDL_arraysize(dylib_locations); i++) { const char *location = dylib_locations[i]; if (location) { Loaded_SDL20 = dlopen(location, RTLD_LOCAL|RTLD_NOW); @@ -1108,7 +1108,7 @@ static char loaderror[256]; if (homedir) { char framework[512]; const int rc = snprintf(framework, sizeof (framework), "%s/Library/Frameworks/" SDL20_FRAMEWORK, homedir); - if ((rc > 0) && (rc < sizeof (framework))) { + if ((rc > 0) && (rc < (int) sizeof(framework))) { Loaded_SDL20 = dlopen(framework, RTLD_LOCAL|RTLD_NOW); } } @@ -1286,7 +1286,7 @@ SDL12Compat_ApplyQuirks(void) if (*exe_name == '\0') { return; } - for (i = 0; i < SDL_arraysize(quirks); i++) { + for (i = 0; i < (int) SDL_arraysize(quirks); i++) { if (!SDL20_strcmp(exe_name, quirks[i].exe_name)) { if (!SDL20_getenv(quirks[i].hint_name)) { if (debug_logging) { @@ -2080,7 +2080,7 @@ Init12VidModes(void) /* Attempt to add all of the fake modes. */ if (use_fake_modes) { - for (j = 0; j < SDL_arraysize(fake_modes); ++j) { + for (j = 0; j < (int) SDL_arraysize(fake_modes); ++j) { if (VidModeSizeGreater(&prev_mode, &fake_modes[j]) && VidModeSizeGreater(&fake_modes[j], ¤t_mode)) { if (AddVidModeToList(vmode, &fake_modes[j])) { return SDL20_OutOfMemory(); @@ -2099,7 +2099,7 @@ Init12VidModes(void) /* we need to try to add fake modes to the end of the list once there are no more real modes */ if (use_fake_modes) { - for (i = 0; i < SDL_arraysize(fake_modes); ++i) { + for (i = 0; i < (int) SDL_arraysize(fake_modes); ++i) { if (VidModeSizeGreater(&prev_mode, &fake_modes[i])) { if (AddVidModeToList(vmode, &fake_modes[i])) { return SDL20_OutOfMemory(); @@ -2156,7 +2156,7 @@ HasWmAvailable(const char *driver) }; int i; - for (i = 0; i < SDL_arraysize(gui_targets); i++) { + for (i = 0; i < (int) SDL_arraysize(gui_targets); i++) { if (SDL20_strcasecmp(driver, gui_targets[i]) == 0) { return 1; } From d9d0a0a1121296bd963c3b4374686234fedb397c Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sun, 4 Sep 2022 09:12:15 -0400 Subject: [PATCH 324/606] Force stack alignment on public entry points for 32-bit x86 Linux. This helps make extremely old binaries (like the Loki games) less crashy on modern systems for almost no extra cost. Reference Issue #176. --- src/SDL12_compat.c | 322 +++++++++++++++++++++++---------------------- 1 file changed, 167 insertions(+), 155 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 72d658275..fe83a30fd 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -80,6 +80,18 @@ extern "C" { #endif +/* on x86 Linux builds, we have the public entry points force stack alignment to 16 bytes + on entry. This won't be a massive performance hit, but it might help extremely old + binaries that want to call into SDL to not crash in hard-to-diagnose ways. It's not a + panacea to the stack alignment problem, but it might help a little. */ +#if defined(__linux__) && defined(__i386__) && (defined(__GNUC__) || defined(__clang__)) +#define FORCEALIGNATTR __attribute__((force_align_arg_pointer)) +#else +#define FORCEALIGNATTR __attribute__((force_align_arg_pointer)) +#endif + +#define DECLSPEC12 DECLSPEC FORCEALIGNATTR + #define SDL20_SYM(rc,fn,params,args,ret) \ typedef rc (SDLCALL *SDL20_##fn##_t) params; \ static SDL20_##fn##_t SDL20_##fn = NULL; @@ -87,7 +99,7 @@ extern "C" { /* Things that _should_ be binary compatible pass right through... */ #define SDL20_SYM_PASSTHROUGH(rc,fn,params,args,ret) \ - DECLSPEC rc SDLCALL SDL_##fn params { ret SDL20_##fn args; } + DECLSPEC12 rc SDLCALL SDL_##fn params { ret SDL20_##fn args; } #include "SDL20_syms.h" @@ -1430,21 +1442,21 @@ unsigned _System LibMain(unsigned hmod, unsigned termination) * SDL2 doesn't define SDL_MAIN_NEEDED for _WIN32, * therefore no need to call SDL_SetMainReady(). */ -DECLSPEC void SDLCALL +DECLSPEC12 void SDLCALL SDL_SetModuleHandle(void *handle) { (void) handle;/* handled internally by SDL2 - nothing to do.. */ } #endif -DECLSPEC const SDL_version * SDLCALL +DECLSPEC12 const SDL_version * SDLCALL SDL_Linked_Version(void) { static const SDL_version version = { 1, 2, SDL12_COMPAT_VERSION }; return &version; } -DECLSPEC int SDLCALL +DECLSPEC12 int SDLCALL SDL_sscanf(const char *text, const char *fmt, ...) { int retval; @@ -1455,7 +1467,7 @@ SDL_sscanf(const char *text, const char *fmt, ...) return retval; } -DECLSPEC int SDLCALL +DECLSPEC12 int SDLCALL SDL_snprintf(char *text, size_t maxlen, const char *fmt, ...) { int retval; @@ -1466,7 +1478,7 @@ SDL_snprintf(char *text, size_t maxlen, const char *fmt, ...) return retval; } -DECLSPEC void * SDLCALL +DECLSPEC12 void * SDLCALL SDL_revcpy(void *_dst, const void *_src, size_t len) { if (len > 0) { @@ -1543,13 +1555,13 @@ static int get_cpu_ext_features(void) { return cpu_ext_features; } -DECLSPEC SDL_bool SDLCALL +DECLSPEC12 SDL_bool SDLCALL SDL_HasMMXExt(void) { return (get_cpu_ext_features() & 0x00400000)? SDL_TRUE : SDL_FALSE; } -DECLSPEC SDL_bool SDLCALL +DECLSPEC12 SDL_bool SDLCALL SDL_Has3DNowExt(void) { return (get_cpu_ext_features() & 0x40000000)? SDL_TRUE : SDL_FALSE; @@ -1687,13 +1699,13 @@ Quit12Joystick(void) NumJoysticks = 0; } -DECLSPEC int SDLCALL +DECLSPEC12 int SDLCALL SDL_NumJoysticks(void) { return NumJoysticks; } -DECLSPEC int SDLCALL +DECLSPEC12 int SDLCALL SDL_JoystickNumAxes(SDL12_Joystick *stick12) { if (BogusJoystick(stick12)) { @@ -1702,7 +1714,7 @@ SDL_JoystickNumAxes(SDL12_Joystick *stick12) return JoysticksAreGameControllers ? (SDL_CONTROLLER_AXIS_MAX + 1) : SDL20_JoystickNumAxes(stick12->dev.joystick); } -DECLSPEC int SDLCALL +DECLSPEC12 int SDLCALL SDL_JoystickNumBalls(SDL12_Joystick *stick12) { if (BogusJoystick(stick12)) { @@ -1711,7 +1723,7 @@ SDL_JoystickNumBalls(SDL12_Joystick *stick12) return JoysticksAreGameControllers ? 0 : SDL20_JoystickNumBalls(stick12->dev.joystick); } -DECLSPEC int SDLCALL +DECLSPEC12 int SDLCALL SDL_JoystickNumHats(SDL12_Joystick *stick12) { if (BogusJoystick(stick12)) { @@ -1720,7 +1732,7 @@ SDL_JoystickNumHats(SDL12_Joystick *stick12) return JoysticksAreGameControllers ? 0 : SDL20_JoystickNumHats(stick12->dev.joystick); } -DECLSPEC int SDLCALL +DECLSPEC12 int SDLCALL SDL_JoystickNumButtons(SDL12_Joystick *stick12) { if (BogusJoystick(stick12)) { @@ -1729,7 +1741,7 @@ SDL_JoystickNumButtons(SDL12_Joystick *stick12) return JoysticksAreGameControllers ? (SDL_CONTROLLER_BUTTON_MAX + 1) : SDL20_JoystickNumButtons(stick12->dev.joystick); } -DECLSPEC void SDLCALL +DECLSPEC12 void SDLCALL SDL_JoystickUpdate(void) { if (JoysticksAreGameControllers) { @@ -1739,7 +1751,7 @@ SDL_JoystickUpdate(void) } } -DECLSPEC int SDLCALL +DECLSPEC12 int SDLCALL SDL_JoystickEventState(int state) { switch (state) { @@ -1757,7 +1769,7 @@ SDL_JoystickEventState(int state) } } -DECLSPEC Sint16 SDLCALL +DECLSPEC12 Sint16 SDLCALL SDL_JoystickGetAxis(SDL12_Joystick *stick12, int axis) { if (BogusJoystick(stick12)) { @@ -1766,7 +1778,7 @@ SDL_JoystickGetAxis(SDL12_Joystick *stick12, int axis) return JoysticksAreGameControllers ? SDL20_GameControllerGetAxis(stick12->dev.controller, axis) : SDL20_JoystickGetAxis(stick12->dev.joystick, axis); } -DECLSPEC Uint8 SDLCALL +DECLSPEC12 Uint8 SDLCALL SDL_JoystickGetHat(SDL12_Joystick *stick12, int hat) { if (BogusJoystick(stick12)) { @@ -1775,7 +1787,7 @@ SDL_JoystickGetHat(SDL12_Joystick *stick12, int hat) return JoysticksAreGameControllers ? 0 : SDL20_JoystickGetHat(stick12->dev.joystick, hat); } -DECLSPEC int SDLCALL +DECLSPEC12 int SDLCALL SDL_JoystickGetBall(SDL12_Joystick *stick12, int ball, int *dx, int *dy) { if (BogusJoystick(stick12)) { @@ -1788,7 +1800,7 @@ SDL_JoystickGetBall(SDL12_Joystick *stick12, int ball, int *dx, int *dy) return SDL20_JoystickGetBall(stick12->dev.joystick, ball, dx, dy); } -DECLSPEC Uint8 SDLCALL +DECLSPEC12 Uint8 SDLCALL SDL_JoystickGetButton(SDL12_Joystick *stick12, int button) { if (BogusJoystick(stick12)) { @@ -1797,7 +1809,7 @@ SDL_JoystickGetButton(SDL12_Joystick *stick12, int button) return JoysticksAreGameControllers ? SDL20_GameControllerGetButton(stick12->dev.controller, button) : SDL20_JoystickGetButton(stick12->dev.joystick, button); } -DECLSPEC SDL12_Joystick * SDLCALL +DECLSPEC12 SDL12_Joystick * SDLCALL SDL_JoystickOpen(int device_index) { if (BogusJoystickIndex(device_index)) { @@ -1809,7 +1821,7 @@ SDL_JoystickOpen(int device_index) return &JoystickList[device_index]; } -DECLSPEC void SDLCALL +DECLSPEC12 void SDLCALL SDL_JoystickClose(SDL12_Joystick *stick12) { if (!BogusJoystick(stick12)) { @@ -1820,19 +1832,19 @@ SDL_JoystickClose(SDL12_Joystick *stick12) } } -DECLSPEC const char * SDLCALL +DECLSPEC12 const char * SDLCALL SDL_JoystickName(int device_index) { return BogusJoystickIndex(device_index) ? NULL : JoystickList[device_index].name; } -DECLSPEC int SDLCALL +DECLSPEC12 int SDLCALL SDL_JoystickIndex(SDL12_Joystick *stick12) { return BogusJoystick(stick12) ? -1 : (int) (stick12 - JoystickList); } -DECLSPEC int SDLCALL +DECLSPEC12 int SDLCALL SDL_JoystickOpened(int device_index) { if (BogusJoystickIndex(device_index)) { @@ -2128,7 +2140,7 @@ Init12VidModes(void) /* we should have a default cursor */ #include "default_cursor.h" -DECLSPEC void SDLCALL SDL_FreeCursor(SDL12_Cursor *); +DECLSPEC12 void SDLCALL SDL_FreeCursor(SDL12_Cursor *); static int HasWmAvailable(const char *driver) @@ -2165,7 +2177,7 @@ HasWmAvailable(const char *driver) return 0; } -DECLSPEC int SDLCALL SDL_EnableKeyRepeat(int delay, int interval); +DECLSPEC12 int SDLCALL SDL_EnableKeyRepeat(int delay, int interval); static int Init12Video(void) @@ -2237,7 +2249,7 @@ Init12Video(void) return 0; } -DECLSPEC int SDLCALL +DECLSPEC12 int SDLCALL SDL_VideoInit(const char *driver, Uint32 flags) { int retval; @@ -2259,7 +2271,7 @@ static void InitializeCDSubsystem(void); static void QuitCDSubsystem(void); -DECLSPEC int SDLCALL +DECLSPEC12 int SDLCALL SDL_InitSubSystem(Uint32 sdl12flags) { Uint32 sdl20flags = 0; @@ -2343,7 +2355,7 @@ SDL_InitSubSystem(Uint32 sdl12flags) return rc; } -DECLSPEC int SDLCALL +DECLSPEC12 int SDLCALL SDL_Init(Uint32 sdl12flags) { return SDL_InitSubSystem(sdl12flags); /* there's no difference betwee Init and InitSubSystem in SDL2. */ @@ -2389,7 +2401,7 @@ InitFlags20to12(const Uint32 flags20) } -DECLSPEC Uint32 SDLCALL +DECLSPEC12 Uint32 SDLCALL SDL_WasInit(Uint32 sdl12flags) { Uint32 sdl20flags, extraflags; @@ -2438,7 +2450,7 @@ Quit12Video(void) EventThreadEnabled = SDL_FALSE; } -DECLSPEC void SDLCALL +DECLSPEC12 void SDLCALL SDL_QuitSubSystem(Uint32 sdl12flags) { Uint32 sdl20flags, extraflags; @@ -2478,20 +2490,20 @@ SDL_QuitSubSystem(Uint32 sdl12flags) InitializedSubsystems20 &= ~SDL_INIT_NOPARACHUTE; /* SDL2 accepts this flag but ignores it. */ } -DECLSPEC void SDLCALL +DECLSPEC12 void SDLCALL SDL_Quit(void) { SDL_QuitSubSystem(SDL_WasInit(0) | SDL12_INIT_CDROM); SDL_assert((InitializedSubsystems20 == 0) || (SDL12Compat_GetHintBoolean("SDL12COMPAT_NO_QUIT_VIDEO", SDL_FALSE) && (InitializedSubsystems20 == SDL_INIT_VIDEO))); } -DECLSPEC void SDLCALL +DECLSPEC12 void SDLCALL SDL_Error(SDL_errorcode error) { SDL20_Error(error); } -DECLSPEC void SDLCALL +DECLSPEC12 void SDLCALL SDL_SetError(const char *fmt, ...) { char ch; @@ -2515,7 +2527,7 @@ SDL_SetError(const char *fmt, ...) } } -DECLSPEC const char * SDLCALL +DECLSPEC12 const char * SDLCALL SDL_GetError(void) { if (SDL20_GetError == NULL) { @@ -2540,13 +2552,13 @@ GetDriverName(const char *name, char *namebuf, int maxlen) return NULL; } -DECLSPEC const char * SDLCALL +DECLSPEC12 const char * SDLCALL SDL_AudioDriverName(char *namebuf, int maxlen) { return GetDriverName(SDL20_GetCurrentAudioDriver(), namebuf, maxlen); } -DECLSPEC const char * SDLCALL +DECLSPEC12 const char * SDLCALL SDL_VideoDriverName(char *namebuf, int maxlen) { return GetDriverName(SDL20_GetCurrentVideoDriver(), namebuf, maxlen); @@ -2579,7 +2591,7 @@ SDL_PollEvent_locked(SDL12_Event *event12) return 1; } -DECLSPEC int SDLCALL +DECLSPEC12 int SDLCALL SDL_PollEvent(SDL12_Event *event12) { int retval; @@ -2623,7 +2635,7 @@ SDL_PushEvent_locked(SDL12_Event *event12) return 0; } -DECLSPEC int SDLCALL +DECLSPEC12 int SDLCALL SDL_PushEvent(SDL12_Event *event12) { int retval; @@ -2716,7 +2728,7 @@ SDL_PeepEvents_locked(SDL12_Event *events12, int numevents, SDL_eventaction acti return 0; } -DECLSPEC int SDLCALL +DECLSPEC12 int SDLCALL SDL_PeepEvents(SDL12_Event *events12, int numevents, SDL_eventaction action, Uint32 mask) { int retval; @@ -2732,7 +2744,7 @@ SDL_PeepEvents(SDL12_Event *events12, int numevents, SDL_eventaction action, Uin return retval; } -DECLSPEC int SDLCALL +DECLSPEC12 int SDLCALL SDL_WaitEvent(SDL12_Event *event12) { if (!EventQueueMutex) { @@ -2764,7 +2776,7 @@ PushEventIfNotFiltered(SDL12_Event *event12) return retval; } -DECLSPEC Uint8 SDLCALL +DECLSPEC12 Uint8 SDLCALL SDL_EventState(Uint8 type, int state) { Uint8 retval = 0; @@ -2913,7 +2925,7 @@ static Uint8 MouseButtonState20to12(const Uint32 state20) return retval; } -DECLSPEC Uint8 SDLCALL +DECLSPEC12 Uint8 SDLCALL SDL_GetMouseState(int *x, int *y) { const Uint8 buttons = MouseButtonState20to12(SDL20_GetMouseState(x, y)); @@ -2922,13 +2934,13 @@ SDL_GetMouseState(int *x, int *y) return buttons; } -DECLSPEC Uint8 SDLCALL +DECLSPEC12 Uint8 SDLCALL SDL_GetRelativeMouseState(int *x, int *y) { return MouseButtonState20to12(SDL20_GetRelativeMouseState(x, y)); } -DECLSPEC char * SDLCALL +DECLSPEC12 char * SDLCALL SDL_GetKeyName(SDL12Key key) { switch (key) { @@ -4194,7 +4206,7 @@ Scancode20to12(SDL_Scancode sc) } } -DECLSPEC Uint8 * SDLCALL +DECLSPEC12 Uint8 * SDLCALL SDL_GetKeyState(int *numkeys) { if (numkeys) { @@ -4653,14 +4665,14 @@ EventFilter20to12(void *data, SDL_Event *event20) return 1; } -DECLSPEC void SDLCALL +DECLSPEC12 void SDLCALL SDL_SetEventFilter(SDL12_EventFilter filter12) { /* We always have a filter installed, but will call the app's too. */ EventFilter12 = filter12; } -DECLSPEC SDL12_EventFilter SDLCALL +DECLSPEC12 SDL12_EventFilter SDLCALL SDL_GetEventFilter(void) { return EventFilter12; @@ -4851,7 +4863,7 @@ SetPalette12ForMasks(SDL12_Surface *surface12, const Uint32 Rmask, const Uint32 } } -DECLSPEC SDL12_Surface * SDLCALL +DECLSPEC12 SDL12_Surface * SDLCALL SDL_CreateRGBSurface(Uint32 flags12, int width, int height, int depth, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask) { SDL_Surface *surface20; @@ -4902,7 +4914,7 @@ SDL_CreateRGBSurface(Uint32 flags12, int width, int height, int depth, Uint32 Rm return surface12; } -DECLSPEC SDL12_Surface * SDLCALL +DECLSPEC12 SDL12_Surface * SDLCALL SDL_CreateRGBSurfaceFrom(void *pixels, int width, int height, int depth, int pitch, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask) { SDL_Surface *surface20; @@ -4932,7 +4944,7 @@ SDL_CreateRGBSurfaceFrom(void *pixels, int width, int height, int depth, int pit return surface12; } -DECLSPEC void SDLCALL +DECLSPEC12 void SDLCALL SDL_FreeSurface(SDL12_Surface *surface12) { if (surface12 && (surface12 != VideoSurface12)) { @@ -4948,7 +4960,7 @@ SDL_FreeSurface(SDL12_Surface *surface12) } } -DECLSPEC void SDLCALL +DECLSPEC12 void SDLCALL SDL_GetClipRect(SDL12_Surface *surface12, SDL12_Rect *rect) { if (surface12 && rect) { @@ -4956,7 +4968,7 @@ SDL_GetClipRect(SDL12_Surface *surface12, SDL12_Rect *rect) } } -DECLSPEC SDL_bool SDLCALL +DECLSPEC12 SDL_bool SDLCALL SDL_SetClipRect(SDL12_Surface *surface12, const SDL12_Rect *rect12) { SDL_bool retval = SDL_FALSE; @@ -4969,7 +4981,7 @@ SDL_SetClipRect(SDL12_Surface *surface12, const SDL12_Rect *rect12) return retval; } -DECLSPEC int SDLCALL +DECLSPEC12 int SDLCALL SDL_FillRect(SDL12_Surface *dst, SDL12_Rect *dstrect12, Uint32 color) { SDL_Rect dstrect20; @@ -4984,7 +4996,7 @@ SDL_FillRect(SDL12_Surface *dst, SDL12_Rect *dstrect12, Uint32 color) return retval; } -DECLSPEC Uint32 SDLCALL +DECLSPEC12 Uint32 SDLCALL SDL_MapRGB(const SDL12_PixelFormat *format12, Uint8 r, Uint8 g, Uint8 b) { /* This is probably way slower than apps expect. */ @@ -4993,7 +5005,7 @@ SDL_MapRGB(const SDL12_PixelFormat *format12, Uint8 r, Uint8 g, Uint8 b) return SDL20_MapRGB(PixelFormat12to20(&format20, &palette20, format12), r, g, b); } -DECLSPEC Uint32 SDLCALL +DECLSPEC12 Uint32 SDLCALL SDL_MapRGBA(const SDL12_PixelFormat *format12, Uint8 r, Uint8 g, Uint8 b, Uint8 a) { /* This is probably way slower than apps expect. */ @@ -5002,7 +5014,7 @@ SDL_MapRGBA(const SDL12_PixelFormat *format12, Uint8 r, Uint8 g, Uint8 b, Uint8 return SDL20_MapRGBA(PixelFormat12to20(&format20, &palette20, format12), r, g, b, a); } -DECLSPEC void SDLCALL +DECLSPEC12 void SDLCALL SDL_GetRGB(Uint32 pixel, const SDL12_PixelFormat *format12, Uint8 *r, Uint8 *g, Uint8 *b) { /* This is probably way slower than apps expect. */ @@ -5011,7 +5023,7 @@ SDL_GetRGB(Uint32 pixel, const SDL12_PixelFormat *format12, Uint8 *r, Uint8 *g, SDL20_GetRGB(pixel, PixelFormat12to20(&format20, &palette20, format12), r, g, b); } -DECLSPEC void SDLCALL +DECLSPEC12 void SDLCALL SDL_GetRGBA(Uint32 pixel, const SDL12_PixelFormat *format12, Uint8 *r, Uint8 *g, Uint8 *b, Uint8 *a) { /* This is probably way slower than apps expect. */ @@ -5020,13 +5032,13 @@ SDL_GetRGBA(Uint32 pixel, const SDL12_PixelFormat *format12, Uint8 *r, Uint8 *g, SDL20_GetRGBA(pixel, PixelFormat12to20(&format20, &palette20, format12), r, g, b, a); } -DECLSPEC const SDL12_VideoInfo * SDLCALL +DECLSPEC12 const SDL12_VideoInfo * SDLCALL SDL_GetVideoInfo(void) { return VideoInfo12.vfmt ? &VideoInfo12 : NULL; } -DECLSPEC int SDLCALL +DECLSPEC12 int SDLCALL SDL_VideoModeOK(int width, int height, int bpp, Uint32 sdl12flags) { int i, j, actual_bpp = 0; @@ -5061,7 +5073,7 @@ SDL_VideoModeOK(int width, int height, int bpp, Uint32 sdl12flags) return (actual_bpp == 24) ? 32 : actual_bpp; } -DECLSPEC SDL12_Rect ** SDLCALL +DECLSPEC12 SDL12_Rect ** SDLCALL SDL_ListModes(const SDL12_PixelFormat *format12, Uint32 flags) { VideoModeList *best_modes = NULL; @@ -5112,7 +5124,7 @@ SDL_ListModes(const SDL12_PixelFormat *format12, Uint32 flags) return best_modes->modes12; } -DECLSPEC void SDLCALL +DECLSPEC12 void SDLCALL SDL_FreeCursor(SDL12_Cursor *cursor12) { if (cursor12 == CurrentCursor12) { @@ -5128,7 +5140,7 @@ SDL_FreeCursor(SDL12_Cursor *cursor12) } } -DECLSPEC SDL12_Cursor * SDLCALL +DECLSPEC12 SDL12_Cursor * SDLCALL SDL_CreateCursor(Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y) { const size_t datasize = h * (w / 8); @@ -5177,14 +5189,14 @@ SDL_CreateCursor(Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y) return NULL; } -DECLSPEC void SDLCALL +DECLSPEC12 void SDLCALL SDL_SetCursor(SDL12_Cursor *cursor) { CurrentCursor12 = cursor; SDL20_SetCursor(cursor ? cursor->wm_cursor : NULL); } -DECLSPEC SDL12_Cursor * SDLCALL +DECLSPEC12 SDL12_Cursor * SDLCALL SDL_GetCursor(void) { if (!CurrentCursor12) { @@ -5600,7 +5612,7 @@ static void ResetVideoRendererForThreading(void) static void HandleInputGrab(SDL12_GrabMode mode); -DECLSPEC SDL12_Surface * SDLCALL +DECLSPEC12 SDL12_Surface * SDLCALL SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12) { SDL_DisplayMode dmode; @@ -6035,7 +6047,7 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12) return VideoSurface12; } -DECLSPEC SDL12_Surface * SDLCALL +DECLSPEC12 SDL12_Surface * SDLCALL SDL_GetVideoSurface(void) { return VideoSurface12; @@ -6138,7 +6150,7 @@ RestoreDestAlpha(SDL12_Surface *dst12, Uint8 *dstalpha, const SDL12_Rect *dstrec } } -DECLSPEC int SDLCALL +DECLSPEC12 int SDLCALL SDL_UpperBlit(SDL12_Surface *src12, SDL12_Rect *srcrect12, SDL12_Surface *dst12, SDL12_Rect *dstrect12) { Uint8 *dstalpha; @@ -6165,7 +6177,7 @@ SDL_UpperBlit(SDL12_Surface *src12, SDL12_Rect *srcrect12, SDL12_Surface *dst12, return retval; } -DECLSPEC int SDLCALL +DECLSPEC12 int SDLCALL SDL_LowerBlit(SDL12_Surface *src12, SDL12_Rect *srcrect12, SDL12_Surface *dst12, SDL12_Rect *dstrect12) { Uint8 *dstalpha; @@ -6194,7 +6206,7 @@ SDL_LowerBlit(SDL12_Surface *src12, SDL12_Rect *srcrect12, SDL12_Surface *dst12, return retval; } -DECLSPEC int SDLCALL +DECLSPEC12 int SDLCALL SDL_SoftStretch(SDL12_Surface *src12, SDL12_Rect *srcrect12, SDL12_Surface *dst12, SDL12_Rect *dstrect12) { SDL_Rect srcrect20, dstrect20; @@ -6204,7 +6216,7 @@ SDL_SoftStretch(SDL12_Surface *src12, SDL12_Rect *srcrect12, SDL12_Surface *dst1 dstrect12 ? Rect12to20(dstrect12, &dstrect20) : NULL); } -DECLSPEC int SDLCALL +DECLSPEC12 int SDLCALL SDL_SetAlpha(SDL12_Surface *surface12, Uint32 flags12, Uint8 value) { /* note that SDL 1.2 does not check if surface12 is NULL before dereferencing it either */ @@ -6234,7 +6246,7 @@ SDL_SetAlpha(SDL12_Surface *surface12, Uint32 flags12, Uint8 value) return retval; } -DECLSPEC int SDLCALL +DECLSPEC12 int SDLCALL SDL_LockSurface(SDL12_Surface *surface12) { const int retval = SDL20_LockSurface(surface12->surface20); @@ -6243,7 +6255,7 @@ SDL_LockSurface(SDL12_Surface *surface12) return retval; } -DECLSPEC void SDLCALL +DECLSPEC12 void SDLCALL SDL_UnlockSurface(SDL12_Surface *surface12) { SDL20_UnlockSurface(surface12->surface20); @@ -6251,7 +6263,7 @@ SDL_UnlockSurface(SDL12_Surface *surface12) surface12->pitch = surface12->surface20->pitch; } -DECLSPEC SDL12_Surface * SDLCALL +DECLSPEC12 SDL12_Surface * SDLCALL SDL_ConvertSurface(SDL12_Surface *src12, const SDL12_PixelFormat *format12, Uint32 flags12) { Uint32 flags20 = 0; @@ -6278,7 +6290,7 @@ SDL_ConvertSurface(SDL12_Surface *src12, const SDL12_PixelFormat *format12, Uint return retval; } -DECLSPEC SDL12_Surface * SDLCALL +DECLSPEC12 SDL12_Surface * SDLCALL SDL_DisplayFormat(SDL12_Surface *surface12) { const Uint32 flags = surface12->flags & (SDL12_SRCCOLORKEY|SDL12_SRCALPHA|SDL12_RLEACCELOK); @@ -6290,7 +6302,7 @@ SDL_DisplayFormat(SDL12_Surface *surface12) return SDL_ConvertSurface(surface12, VideoSurface12->format, flags); } -DECLSPEC SDL12_Surface * SDLCALL +DECLSPEC12 SDL12_Surface * SDLCALL SDL_DisplayFormatAlpha(SDL12_Surface *surface12) { const Uint32 flags = surface12->flags & (SDL12_SRCALPHA|SDL12_RLEACCELOK); @@ -6393,7 +6405,7 @@ GetDesiredMillisecondsPerFrame() } /* SDL_OPENGLBLIT support APIs. https://discourse.libsdl.org/t/ogl-and-sdl/2775/3 */ -DECLSPEC void SDLCALL +DECLSPEC12 void SDLCALL SDL_GL_Lock(void) { if (!OpenGLBlitTexture) { @@ -6436,7 +6448,7 @@ SDL_GL_Lock(void) } } -DECLSPEC void SDLCALL +DECLSPEC12 void SDLCALL SDL_GL_UpdateRects(int numrects, SDL12_Rect *rects12) { if (OpenGLBlitTexture) { @@ -6486,7 +6498,7 @@ SDL_GL_UpdateRects(int numrects, SDL12_Rect *rects12) } -DECLSPEC void SDLCALL +DECLSPEC12 void SDLCALL SDL_GL_Unlock(void) { if (OpenGLBlitTexture) { @@ -6503,7 +6515,7 @@ SDL_GL_Unlock(void) } -DECLSPEC void SDLCALL +DECLSPEC12 void SDLCALL SDL_UpdateRects(SDL12_Surface *surface12, int numrects, SDL12_Rect *rects12) { /* strangely, SDL 1.2 doesn't check if surface12 is NULL before touching it */ @@ -6583,7 +6595,7 @@ SDL_UpdateRects(SDL12_Surface *surface12, int numrects, SDL12_Rect *rects12) } } -DECLSPEC void SDLCALL +DECLSPEC12 void SDLCALL SDL_UpdateRect(SDL12_Surface *screen12, Sint32 x, Sint32 y, Uint32 w, Uint32 h) { if (screen12) { @@ -6596,7 +6608,7 @@ SDL_UpdateRect(SDL12_Surface *screen12, Sint32 x, Sint32 y, Uint32 w, Uint32 h) } } -DECLSPEC int SDLCALL +DECLSPEC12 int SDLCALL SDL_Flip(SDL12_Surface *surface12) { if (surface12 == VideoSurface12) { @@ -6625,7 +6637,7 @@ HandleKeyRepeat(void) } } -DECLSPEC void SDLCALL +DECLSPEC12 void SDLCALL SDL_PumpEvents(void) { SDL_Event e; @@ -6658,7 +6670,7 @@ SDL_PumpEvents(void) } -DECLSPEC void SDLCALL +DECLSPEC12 void SDLCALL SDL_WM_SetCaption(const char *title, const char *icon) { if (WindowTitle) { @@ -6674,7 +6686,7 @@ SDL_WM_SetCaption(const char *title, const char *icon) } } -DECLSPEC void SDLCALL +DECLSPEC12 void SDLCALL SDL_WM_GetCaption(const char **title, const char **icon) { if (title) { @@ -6685,7 +6697,7 @@ SDL_WM_GetCaption(const char **title, const char **icon) } } -DECLSPEC void SDLCALL +DECLSPEC12 void SDLCALL SDL_WM_SetIcon(SDL12_Surface *icon12, Uint8 *mask) { SDL_BlendMode oldmode; @@ -6744,7 +6756,7 @@ SDL_WM_SetIcon(SDL12_Surface *icon12, Uint8 *mask) } } -DECLSPEC int SDLCALL +DECLSPEC12 int SDLCALL SDL_WM_IconifyWindow(void) { if (VideoWindow20) { @@ -6753,7 +6765,7 @@ SDL_WM_IconifyWindow(void) return 0; } -DECLSPEC int SDLCALL +DECLSPEC12 int SDLCALL SDL_WM_ToggleFullScreen(SDL12_Surface *surface) { int retval = 0; @@ -6803,7 +6815,7 @@ UpdateRelativeMouseMode(void) } } -DECLSPEC int SDLCALL +DECLSPEC12 int SDLCALL SDL_ShowCursor(int toggle) { const int retval = VideoCursorHidden ? 0 : 1; @@ -6834,7 +6846,7 @@ HandleInputGrab(SDL12_GrabMode mode) } } -DECLSPEC SDL12_GrabMode SDLCALL +DECLSPEC12 SDL12_GrabMode SDLCALL SDL_WM_GrabInput(SDL12_GrabMode mode) { if (mode != SDL12_GRAB_QUERY) { @@ -6843,7 +6855,7 @@ SDL_WM_GrabInput(SDL12_GrabMode mode) return VideoWindowGrabbed ? SDL12_GRAB_ON : SDL12_GRAB_OFF; } -DECLSPEC void SDLCALL +DECLSPEC12 void SDLCALL SDL_WarpMouse(Uint16 x, Uint16 y) { if (MouseInputIsRelative) { /* we have to track this ourselves, in case app calls SDL_GetMouseState(). */ @@ -6856,7 +6868,7 @@ SDL_WarpMouse(Uint16 x, Uint16 y) } } -DECLSPEC Uint8 SDLCALL +DECLSPEC12 Uint8 SDLCALL SDL_GetAppState(void) { Uint8 state12 = 0; @@ -6875,7 +6887,7 @@ SDL_GetAppState(void) return state12; } -DECLSPEC int SDLCALL +DECLSPEC12 int SDLCALL SDL_SetColorKey(SDL12_Surface *surface12, Uint32 flag12, Uint32 key) { const SDL_bool addkey = (flag12 & SDL12_SRCCOLORKEY) ? SDL_TRUE : SDL_FALSE; @@ -6893,7 +6905,7 @@ SDL_SetColorKey(SDL12_Surface *surface12, Uint32 flag12, Uint32 key) return retval; } -DECLSPEC int SDLCALL +DECLSPEC12 int SDLCALL SDL_SetPalette(SDL12_Surface *surface12, int flags, const SDL_Color *colors, int firstcolor, int ncolors) { @@ -6959,7 +6971,7 @@ SDL_SetPalette(SDL12_Surface *surface12, int flags, const SDL_Color *colors, return retval; } -DECLSPEC int SDLCALL +DECLSPEC12 int SDLCALL SDL_SetColors(SDL12_Surface *surface12, const SDL_Color * colors, int firstcolor, int ncolors) { @@ -6973,7 +6985,7 @@ static void x11_lock_display(void) {} static void x11_unlock_display(void) {} #endif -DECLSPEC int SDLCALL +DECLSPEC12 int SDLCALL SDL_GetWMInfo(SDL12_SysWMinfo *info12) { SDL_SysWMinfo info20; @@ -7146,7 +7158,7 @@ SDL_GetWMInfo(SDL12_SysWMinfo *info12) return 1; } -DECLSPEC SDL12_Overlay * SDLCALL +DECLSPEC12 SDL12_Overlay * SDLCALL SDL_CreateYUVOverlay(int w, int h, Uint32 format12, SDL12_Surface *display12) { /* SDL 1.2 has you pass the screen surface in here, but it doesn't check that it's _actually_ the screen surface, @@ -7235,7 +7247,7 @@ SDL_CreateYUVOverlay(int w, int h, Uint32 format12, SDL12_Surface *display12) return retval; } -DECLSPEC int SDLCALL +DECLSPEC12 int SDLCALL SDL_LockYUVOverlay(SDL12_Overlay *overlay12) { SDL12_YUVData *hwdata; @@ -7258,7 +7270,7 @@ SDL_LockYUVOverlay(SDL12_Overlay *overlay12) return 0; /* success */ } -DECLSPEC int SDLCALL +DECLSPEC12 int SDLCALL SDL_DisplayYUVOverlay(SDL12_Overlay *overlay12, SDL12_Rect *dstrect12) { QueuedOverlayItem *overlay; @@ -7332,7 +7344,7 @@ SDL_DisplayYUVOverlay(SDL12_Overlay *overlay12, SDL12_Rect *dstrect12) return 0; } -DECLSPEC void SDLCALL +DECLSPEC12 void SDLCALL SDL_UnlockYUVOverlay(SDL12_Overlay *overlay12) { if (overlay12) { @@ -7340,7 +7352,7 @@ SDL_UnlockYUVOverlay(SDL12_Overlay *overlay12) } } -DECLSPEC void SDLCALL +DECLSPEC12 void SDLCALL SDL_FreeYUVOverlay(SDL12_Overlay *overlay12) { if (overlay12) { @@ -7358,7 +7370,7 @@ SDL_FreeYUVOverlay(SDL12_Overlay *overlay12) } } -DECLSPEC void * SDLCALL +DECLSPEC12 void * SDLCALL SDL_GL_GetProcAddress(const char *sym) { /* see comments on glBindFramebuffer_shim_for_scaling for explanation */ @@ -7391,7 +7403,7 @@ SDL_GL_GetProcAddress(const char *sym) return SDL20_GL_GetProcAddress(sym); } -DECLSPEC int SDLCALL +DECLSPEC12 int SDLCALL SDL_GL_LoadLibrary(const char *libname) { /* SDL 1.2 would unload the previous library if one was loaded. SDL2 @@ -7422,7 +7434,7 @@ SDL_GL_LoadLibrary(const char *libname) } -DECLSPEC int SDLCALL +DECLSPEC12 int SDLCALL SDL_GL_SetAttribute(SDL12_GLattr attr, int value) { if (attr >= SDL12_GL_MAX_ATTRIBUTE) { @@ -7444,7 +7456,7 @@ SDL_GL_SetAttribute(SDL12_GLattr attr, int value) return SDL20_GL_SetAttribute((SDL_GLattr) attr, value); } -DECLSPEC int SDLCALL +DECLSPEC12 int SDLCALL SDL_GL_GetAttribute(SDL12_GLattr attr, int* value) { int retval; @@ -7481,7 +7493,7 @@ SDL_GL_GetAttribute(SDL12_GLattr attr, int* value) } -DECLSPEC void SDLCALL +DECLSPEC12 void SDLCALL SDL_GL_SwapBuffers(void) { if (VideoWindow20) { @@ -7539,7 +7551,7 @@ SDL_GL_SwapBuffers(void) } } -DECLSPEC int SDLCALL +DECLSPEC12 int SDLCALL SDL_SetGamma(float red, float green, float blue) { Uint16 red_ramp[256]; @@ -7563,19 +7575,19 @@ SDL_SetGamma(float red, float green, float blue) return SDL20_SetWindowGammaRamp(VideoWindow20, red_ramp, green_ramp, blue_ramp); } -DECLSPEC int SDLCALL +DECLSPEC12 int SDLCALL SDL_SetGammaRamp(const Uint16 *red, const Uint16 *green, const Uint16 *blue) { return SDL20_SetWindowGammaRamp(VideoWindow20, red, green, blue); } -DECLSPEC int SDLCALL +DECLSPEC12 int SDLCALL SDL_GetGammaRamp(Uint16 *red, Uint16 *green, Uint16 *blue) { return SDL20_GetWindowGammaRamp(VideoWindow20, red, green, blue); } -DECLSPEC int SDLCALL +DECLSPEC12 int SDLCALL SDL_EnableKeyRepeat(int delay, int interval) { if ((delay < 0) || (interval < 0)) { @@ -7589,7 +7601,7 @@ SDL_EnableKeyRepeat(int delay, int interval) return 0; } -DECLSPEC void SDLCALL +DECLSPEC12 void SDLCALL SDL_GetKeyRepeat(int *delay, int *interval) { if (delay) { @@ -7600,7 +7612,7 @@ SDL_GetKeyRepeat(int *delay, int *interval) } } -DECLSPEC int SDLCALL +DECLSPEC12 int SDLCALL SDL_EnableUNICODE(int enable) { const int old = EnabledUnicode; @@ -7629,7 +7641,7 @@ SetTimerCallback12(Uint32 interval, void* param) return RoundTimerTo12Resolution(((SDL12_TimerCallback)param)(interval)); } -DECLSPEC int SDLCALL +DECLSPEC12 int SDLCALL SDL_SetTimer(Uint32 interval, SDL12_TimerCallback callback) { static SDL_TimerID compat_timer; @@ -7649,7 +7661,7 @@ SDL_SetTimer(Uint32 interval, SDL12_TimerCallback callback) return 0; } -DECLSPEC int SDLCALL +DECLSPEC12 int SDLCALL SDL_putenv(const char *_var) { char *ptr = NULL; @@ -7686,20 +7698,20 @@ SDL_putenv(const char *_var) * each other. * * Therefore, we have to do the following trick below. */ -DECLSPEC SDL_Thread * SDLCALL +DECLSPEC12 SDL_Thread * SDLCALL SDL_CreateThread(int (SDLCALL *fn)(void *), void *data) { return SDL20_CreateThread(fn, NULL, data, NULL, NULL); } #else -DECLSPEC SDL_Thread * SDLCALL +DECLSPEC12 SDL_Thread * SDLCALL SDL_CreateThread(int (SDLCALL *fn)(void *), void *data, pfnSDL_CurrentBeginThread pfnBeginThread, pfnSDL_CurrentEndThread pfnEndThread) { return SDL20_CreateThread(fn, NULL, data, pfnBeginThread, pfnEndThread); } #endif #else -DECLSPEC SDL_Thread * SDLCALL +DECLSPEC12 SDL_Thread * SDLCALL SDL_CreateThread(int (SDLCALL *fn)(void *), void *data) { return SDL20_CreateThread(fn, NULL, data); @@ -7708,28 +7720,28 @@ SDL_CreateThread(int (SDLCALL *fn)(void *), void *data) /* These two will truncate the returned value on LP64 systems, * a shortcoming of SDL-1.2. */ -DECLSPEC Uint32 SDLCALL SDL_ThreadID(void) +DECLSPEC12 Uint32 SDLCALL SDL_ThreadID(void) { return SDL20_ThreadID(); } -DECLSPEC Uint32 SDLCALL SDL_GetThreadID(SDL_Thread *thread) +DECLSPEC12 Uint32 SDLCALL SDL_GetThreadID(SDL_Thread *thread) { return SDL20_GetThreadID(thread); } -DECLSPEC int SDLCALL +DECLSPEC12 int SDLCALL SDL_mutexP(SDL_mutex *mutex) { return SDL20_LockMutex(mutex); } -DECLSPEC int SDLCALL +DECLSPEC12 int SDLCALL SDL_mutexV(SDL_mutex *mutex) { return SDL20_UnlockMutex(mutex); } -DECLSPEC void SDLCALL +DECLSPEC12 void SDLCALL SDL_KillThread(SDL_Thread *thread) { (void)thread; @@ -7744,7 +7756,7 @@ AddTimerCallback12(Uint32 interval, void *param) return RoundTimerTo12Resolution(data->callback(interval, data->param)); } -DECLSPEC SDL12_TimerID SDLCALL +DECLSPEC12 SDL12_TimerID SDLCALL SDL_AddTimer(Uint32 interval, SDL12_NewTimerCallback callback, void *param) { SDL12_TimerID data = (SDL12_TimerID) SDL20_malloc(sizeof (SDL12_TimerID_Data)); @@ -7781,7 +7793,7 @@ SDL_AddTimer(Uint32 interval, SDL12_NewTimerCallback callback, void *param) return data; } -DECLSPEC SDL_bool SDLCALL +DECLSPEC12 SDL_bool SDLCALL SDL_RemoveTimer(SDL12_TimerID data) { SDL_bool retval = SDL_FALSE; @@ -7837,7 +7849,7 @@ typedef struct SDL12_RWops { } SDL12_RWops; -DECLSPEC SDL12_RWops * SDLCALL +DECLSPEC12 SDL12_RWops * SDLCALL SDL_AllocRW(void) { SDL12_RWops *rwops = (SDL12_RWops *) SDL20_malloc(sizeof (SDL12_RWops)); @@ -7847,7 +7859,7 @@ SDL_AllocRW(void) return rwops; } -DECLSPEC void SDLCALL +DECLSPEC12 void SDLCALL SDL_FreeRW(SDL12_RWops *rwops12) { SDL20_free(rwops12); @@ -7909,7 +7921,7 @@ RWops20to12(SDL_RWops *rwops20) return rwops12; } -DECLSPEC SDL12_RWops * SDLCALL +DECLSPEC12 SDL12_RWops * SDLCALL SDL_RWFromFile(const char *file, const char *mode) { if (!file || !*file || !mode || !*mode) { @@ -7919,26 +7931,26 @@ SDL_RWFromFile(const char *file, const char *mode) return RWops20to12(SDL20_RWFromFile(file, mode)); } -DECLSPEC SDL12_RWops * SDLCALL +DECLSPEC12 SDL12_RWops * SDLCALL SDL_RWFromFP(void *io, int autoclose) { return RWops20to12(SDL20_RWFromFP(io, autoclose)); } -DECLSPEC SDL12_RWops * SDLCALL +DECLSPEC12 SDL12_RWops * SDLCALL SDL_RWFromMem(void *mem, int size) { return RWops20to12(SDL20_RWFromMem(mem, size)); } -DECLSPEC SDL12_RWops * SDLCALL +DECLSPEC12 SDL12_RWops * SDLCALL SDL_RWFromConstMem(const void *mem, int size) { return RWops20to12(SDL20_RWFromConstMem(mem, size)); } #define READ_AND_BYTESWAP(endian, bits) \ - DECLSPEC Uint##bits SDLCALL SDL_Read##endian##bits(SDL12_RWops *rwops12) { \ + DECLSPEC12 Uint##bits SDLCALL SDL_Read##endian##bits(SDL12_RWops *rwops12) { \ Uint##bits val; rwops12->read(rwops12, &val, sizeof (val), 1); \ return SDL_Swap##endian##bits(val); \ } @@ -7952,7 +7964,7 @@ READ_AND_BYTESWAP(BE,64) #undef READ_AND_BYTESWAP #define BYTESWAP_AND_WRITE(endian, bits) \ - DECLSPEC int SDLCALL SDL_Write##endian##bits(SDL12_RWops *rwops12, Uint##bits val) { \ + DECLSPEC12 int SDLCALL SDL_Write##endian##bits(SDL12_RWops *rwops12, Uint##bits val) { \ val = SDL_Swap##endian##bits(val); \ return rwops12->write(rwops12, &val, sizeof (val), 1); \ } @@ -8056,7 +8068,7 @@ RWops12to20(SDL12_RWops *rwops12) return rwops20; } -DECLSPEC SDL12_Surface * SDLCALL +DECLSPEC12 SDL12_Surface * SDLCALL SDL_LoadBMP_RW(SDL12_RWops *rwops12, int freerwops12) { SDL_RWops *rwops20 = RWops12to20(rwops12); @@ -8071,7 +8083,7 @@ SDL_LoadBMP_RW(SDL12_RWops *rwops12, int freerwops12) return surface12; } -DECLSPEC int SDLCALL +DECLSPEC12 int SDLCALL SDL_SaveBMP_RW(SDL12_Surface *surface12, SDL12_RWops *rwops12, int freerwops12) { SDL_RWops *rwops20 = RWops12to20(rwops12); @@ -8082,7 +8094,7 @@ SDL_SaveBMP_RW(SDL12_Surface *surface12, SDL12_RWops *rwops12, int freerwops12) return retval; } -DECLSPEC SDL_AudioSpec * SDLCALL +DECLSPEC12 SDL_AudioSpec * SDLCALL SDL_LoadWAV_RW(SDL12_RWops *rwops12, int freerwops12, SDL_AudioSpec *spec, Uint8 **buf, Uint32 *len) { @@ -8248,7 +8260,7 @@ QuitCDSubsystem(void) CDRomInit = SDL_FALSE; } -DECLSPEC int SDLCALL +DECLSPEC12 int SDLCALL SDL_CDNumDrives(void) { if (!CDSubsystemIsInitialized()) { @@ -8284,13 +8296,13 @@ ValidCDDriveIndex(const int drive) return SDL_TRUE; } -DECLSPEC const char * SDLCALL +DECLSPEC12 const char * SDLCALL SDL_CDName(int drive) { return ValidCDDriveIndex(drive) ? CDRomPath : NULL; } -DECLSPEC SDL12_CD * SDLCALL +DECLSPEC12 SDL12_CD * SDLCALL SDL_CDOpen(int drive) { SDL12_CD *retval; @@ -8452,7 +8464,7 @@ ValidCDDevice(SDL12_CD *cdrom) } -DECLSPEC SDL12_CDstatus SDLCALL +DECLSPEC12 SDL12_CDstatus SDLCALL SDL_CDStatus(SDL12_CD *cdrom) { SDL12_CDstatus retval; @@ -8547,7 +8559,7 @@ StartCDAudioPlaying(SDL12_CD *cdrom, const int start_track, const int start_fram } -DECLSPEC int SDLCALL +DECLSPEC12 int SDLCALL SDL_CDPlayTracks(SDL12_CD *cdrom, int start_track, int start_frame, int ntracks, int nframes) { if ((cdrom = ValidCDDevice(cdrom)) == NULL) { @@ -8572,7 +8584,7 @@ SDL_CDPlayTracks(SDL12_CD *cdrom, int start_track, int start_frame, int ntracks, return StartCDAudioPlaying(cdrom, start_track, start_frame, ntracks, nframes); } -DECLSPEC int SDLCALL +DECLSPEC12 int SDLCALL SDL_CDPlay(SDL12_CD *cdrom, int start, int length) { const Uint32 ui32start = (Uint32) start; @@ -8631,7 +8643,7 @@ SDL_CDPlay(SDL12_CD *cdrom, int start, int length) return StartCDAudioPlaying(cdrom, start_track, start_frame, ntracks, nframes); } -DECLSPEC int SDLCALL +DECLSPEC12 int SDLCALL SDL_CDPause(SDL12_CD *cdrom) { if ((cdrom = ValidCDDevice(cdrom)) == NULL) { @@ -8651,7 +8663,7 @@ SDL_CDPause(SDL12_CD *cdrom) return 0; } -DECLSPEC int SDLCALL +DECLSPEC12 int SDLCALL SDL_CDResume(SDL12_CD *cdrom) { if ((cdrom = ValidCDDevice(cdrom)) == NULL) { @@ -8672,7 +8684,7 @@ SDL_CDResume(SDL12_CD *cdrom) } -DECLSPEC int SDLCALL +DECLSPEC12 int SDLCALL SDL_CDStop(SDL12_CD *cdrom) { SDL_RWops *oldrw = NULL; @@ -8697,7 +8709,7 @@ SDL_CDStop(SDL12_CD *cdrom) return 0; } -DECLSPEC int SDLCALL +DECLSPEC12 int SDLCALL SDL_CDEject(SDL12_CD *cdrom) { if ((cdrom = ValidCDDevice(cdrom)) == NULL) { @@ -8714,7 +8726,7 @@ SDL_CDEject(SDL12_CD *cdrom) return 0; } -DECLSPEC void SDLCALL +DECLSPEC12 void SDLCALL SDL_CDClose(SDL12_CD *cdrom) { if ((cdrom = ValidCDDevice(cdrom)) == NULL) { @@ -8964,7 +8976,7 @@ CloseSDL2AudioDevice(void) } -DECLSPEC int SDLCALL +DECLSPEC12 int SDLCALL SDL_OpenAudio(SDL_AudioSpec *want, SDL_AudioSpec *obtained) { SDL_bool already_opened; @@ -9066,13 +9078,13 @@ SDL_OpenAudio(SDL_AudioSpec *want, SDL_AudioSpec *obtained) return 0; } -DECLSPEC void SDLCALL +DECLSPEC12 void SDLCALL SDL_PauseAudio(int pause_on) { SDL20_AtomicSet(&audio_callback_paused, pause_on ? SDL_TRUE : SDL_FALSE); } -DECLSPEC SDL_AudioStatus SDLCALL +DECLSPEC12 SDL_AudioStatus SDLCALL SDL_GetAudioStatus(void) { SDL_AudioStatus retval = SDL_AUDIO_STOPPED; @@ -9084,7 +9096,7 @@ SDL_GetAudioStatus(void) return retval; } -DECLSPEC void SDLCALL +DECLSPEC12 void SDLCALL SDL_CloseAudio(void) { SDL20_LockAudio(); @@ -9135,7 +9147,7 @@ AudioCVT20to12(const SDL_AudioCVT *cvt20, SDL12_AudioCVT *cvt12) return cvt12; } -DECLSPEC int SDLCALL +DECLSPEC12 int SDLCALL SDL_BuildAudioCVT(SDL12_AudioCVT *cvt12, Uint16 src_format, Uint8 src_channels, int src_rate, Uint16 dst_format, Uint8 dst_channels, int dst_rate) { SDL_AudioCVT cvt20; @@ -9144,7 +9156,7 @@ SDL_BuildAudioCVT(SDL12_AudioCVT *cvt12, Uint16 src_format, Uint8 src_channels, return retval; } -DECLSPEC int SDLCALL +DECLSPEC12 int SDLCALL SDL_ConvertAudio(SDL12_AudioCVT *cvt12) { /* neither SDL 1.2 nor 2.0 makes sure cvt12 isn't NULL here. :/ */ @@ -9160,13 +9172,13 @@ SDL_ConvertAudio(SDL12_AudioCVT *cvt12) these functions, to let them make a GL context current on a background thread, so we supply them as well to be binary compatible for those games. */ -DECLSPEC void SDLCALL +DECLSPEC12 void SDLCALL SDL_GL_DisableContext(void) { SDL20_GL_MakeCurrent(NULL, NULL); } -DECLSPEC void SDLCALL +DECLSPEC12 void SDLCALL SDL_GL_EnableContext_Thread(void) { const SDL_bool enable = (VideoGLContext20 && VideoWindow20) ? SDL_TRUE : SDL_FALSE; @@ -9183,7 +9195,7 @@ SDL_GL_EnableContext_Thread(void) to Wayland, and if there's some wildly-misbuilt win32 software, they can call it too. :) */ #if !(defined(_WIN32) || defined(__OS2__)) /* #if defined(__unix__) || defined(__APPLE__) ?? */ -DECLSPEC Uint16 SDLCALL +DECLSPEC12 Uint16 SDLCALL X11_KeyToUnicode(SDL12Key key, SDL12Mod mod) { if (((int) key) >= 127) { From 2379757f8b24b3b4d08c08f5cdb56a5643757ddd Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sun, 4 Sep 2022 17:39:00 +0300 Subject: [PATCH 325/606] fix FORCEALIGNATTR copy/paste mistake TODO: force_align_arg_pointer attribute requires gcc >= 4.2: adjust so. --- src/SDL12_compat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index fe83a30fd..a82374696 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -87,7 +87,7 @@ extern "C" { #if defined(__linux__) && defined(__i386__) && (defined(__GNUC__) || defined(__clang__)) #define FORCEALIGNATTR __attribute__((force_align_arg_pointer)) #else -#define FORCEALIGNATTR __attribute__((force_align_arg_pointer)) +#define FORCEALIGNATTR #endif #define DECLSPEC12 DECLSPEC FORCEALIGNATTR From d4a40827b99afef0d7b90ef7129cc0984b634930 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sun, 4 Sep 2022 18:11:40 +0300 Subject: [PATCH 326/606] make sure we have gcc >= 4.2.x before enabling force_align_arg_pointer --- src/SDL12_compat.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index a82374696..1a2b35fe0 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -83,8 +83,15 @@ extern "C" { /* on x86 Linux builds, we have the public entry points force stack alignment to 16 bytes on entry. This won't be a massive performance hit, but it might help extremely old binaries that want to call into SDL to not crash in hard-to-diagnose ways. It's not a - panacea to the stack alignment problem, but it might help a little. */ -#if defined(__linux__) && defined(__i386__) && (defined(__GNUC__) || defined(__clang__)) + panacea to the stack alignment problem, but it might help a little. + + The force_align_arg_pointer attribute requires gcc >= 4.2.x. */ +#if defined(__clang__) +#define HAVE_FORCE_ALIGN_ARG_POINTER +#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2)) +#define HAVE_FORCE_ALIGN_ARG_POINTER +#endif +#if defined(__linux__) && defined(__i386__) && defined(HAVE_FORCE_ALIGN_ARG_POINTER) #define FORCEALIGNATTR __attribute__((force_align_arg_pointer)) #else #define FORCEALIGNATTR From 9652b894577676957ec7cc958a65876603a256ac Mon Sep 17 00:00:00 2001 From: Joshua Root Date: Mon, 5 Sep 2022 12:22:55 +1000 Subject: [PATCH 327/606] Set DYLIB_COMPAT_VERSION to match SDL-1.2 autotools The compatibility_version is meant to go up when new symbols are added to a library, so an executable built against an older version of a library can run against a newer version of that library, but not the other way round. The most binary compatible approach is therefore to use the highest of the different compatibility_version numbers that could have been used by SDL-1.2. --- CMakeLists.txt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ca88d6814..41c72e992 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,8 +20,10 @@ set(CMAKE_SKIP_RPATH TRUE) if(APPLE) set(OSX_SRCS "src/SDL12_compat_objc.m") set_source_files_properties(${OSX_SRCS} PROPERTIES LANGUAGE C) - # the following matches SDL-1.2 Xcode project file - set(DYLIB_COMPAT_VERSION 1.0.0 CACHE STRING "library compatibility version") + # compatibility version set to match SDL-1.2 autotools build + # Xcode project file uses 1.0.0, but it's more compatible to use the + # higher version. + set(DYLIB_COMPAT_VERSION 12.0.0 CACHE STRING "library compatibility version") set(DYLIB_CURRENT_VERSION 12.54.0 CACHE STRING "library current version") include_directories("/opt/X11/include") # hack. if(CMAKE_VERSION VERSION_LESS 3.9) From 537a13f0345feed1d2587f91a41efcb6cc26a173 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 8 Sep 2022 10:48:54 -0400 Subject: [PATCH 328/606] syswm: Deal with SDL2 versions from before the new SDL2 version scheme. Fixes #168. --- src/SDL12_compat.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 1a2b35fe0..1e460e8cc 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -7019,7 +7019,18 @@ SDL_GetWMInfo(SDL12_SysWMinfo *info12) } SDL_zero(info20); - SDL_VERSION(&info20.version); + + /* SDL2, before the version scheme change, would fail if the requested version wasn't + 2.0.x, so if the SDL2 is from before this was fixed, we need to lie about the + version, and assume it will work out. */ + if (LinkedSDL2VersionInt >= SDL_VERSIONNUM(2,24,0)) { + SDL_VERSION(&info20.version); + } else { + info20.version.major = 2; + info20.version.minor = 0; + info20.version.patch = 22; + } + rc = SDL20_GetWindowWMInfo(win20, &info20); if (temp_window) { From f0199bdb25e2a1483eee7a3dccb95565323dd0b4 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 8 Sep 2022 10:55:42 -0400 Subject: [PATCH 329/606] syswm: The magic SDL_SysWMinfo2on12 hack reports the `SDL_Window *` now, too. Fixes #186. --- include/SDL/SDL_syswm.h | 1 + src/SDL12_compat.c | 2 ++ test/testsyswm2on12.c | 1 + 3 files changed, 4 insertions(+) diff --git a/include/SDL/SDL_syswm.h b/include/SDL/SDL_syswm.h index 2add7d9b7..80865d1a2 100644 --- a/include/SDL/SDL_syswm.h +++ b/include/SDL/SDL_syswm.h @@ -134,6 +134,7 @@ typedef struct SDL_SysWMinfo2on12 void *data6; void *data7; void *data8; + void *sdl2_window; /* this is the SDL2 SDL_Window */ } SDL_SysWMinfo2on12; extern DECLSPEC int SDLCALL SDL_GetWMInfo(SDL_SysWMinfo *info); diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 1e460e8cc..20b5f9dae 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -650,6 +650,7 @@ typedef struct SDL12_SysWMinfo2on12 void *data6; void *data7; void *data8; + void *sdl2_window; } SDL12_SysWMinfo2on12; @@ -7047,6 +7048,7 @@ SDL_GetWMInfo(SDL12_SysWMinfo *info12) SDL_zerop(wminfo2); SDL20_memcpy(&wminfo2->version, &info20.version, sizeof (wminfo2->version)); wminfo2->subsystem = (Uint32) info20.subsystem; /* these do not map to SDL 1.2 values! You're on your own! */ + wminfo2->sdl2_window = VideoWindow20; switch (info20.subsystem) { #if defined(SDL_VIDEO_DRIVER_WINDOWS) diff --git a/test/testsyswm2on12.c b/test/testsyswm2on12.c index 73b000df8..ee2ffa099 100644 --- a/test/testsyswm2on12.c +++ b/test/testsyswm2on12.c @@ -105,6 +105,7 @@ int main(int argc, char **argv) printf("data6: %p\n", syswm_info.data6); printf("data7: %p\n", syswm_info.data7); printf("data8: %p\n", syswm_info.data8); + printf("sdl2_window: %p\n", syswm_info.sdl2_window); } SDL_Quit(); From 1633695e6f42925b46ce52a52f15907021e5c50d Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 8 Sep 2022 11:19:33 -0400 Subject: [PATCH 330/606] hints: Clean up when we check hints, for consistency. --- src/SDL12_compat.c | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 20b5f9dae..3265965c8 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1019,6 +1019,9 @@ static SDL_bool UseMouseRelativeScaling = SDL_FALSE; static OpenGLEntryPoints OpenGLFuncs; static int OpenGLBlitLockCount = 0; static GLuint OpenGLBlitTexture = 0; +static SDL_bool WantDebugLogging = SDL_FALSE; +static SDL_bool WantScaleMethodNearest = SDL_FALSE; +static SDL_bool WantOpenGLScaling = SDL_FALSE; static int OpenGLLogicalScalingWidth = 0; static int OpenGLLogicalScalingHeight = 0; static GLuint OpenGLLogicalScalingFBO = 0; @@ -1299,7 +1302,6 @@ SDL12Compat_GetHintFloat(const char *name, float default_value) static void SDL12Compat_ApplyQuirks(void) { - const SDL_bool debug_logging = SDL12Compat_GetHintBoolean("SDL12COMPAT_DEBUG_LOGGING", SDL_FALSE); const char *exe_name = SDL12Compat_GetExeName(); int i; @@ -1309,12 +1311,12 @@ SDL12Compat_ApplyQuirks(void) for (i = 0; i < (int) SDL_arraysize(quirks); i++) { if (!SDL20_strcmp(exe_name, quirks[i].exe_name)) { if (!SDL20_getenv(quirks[i].hint_name)) { - if (debug_logging) { + if (WantDebugLogging) { SDL20_Log("Applying compatibility quirk %s=\"%s\" for \"%s\"", quirks[i].hint_name, quirks[i].hint_value, exe_name); } SDL20_setenv(quirks[i].hint_name, quirks[i].hint_value, 1); } else { - if (debug_logging) { + if (WantDebugLogging) { SDL20_Log("Not applying compatibility quirk %s=\"%s\" for \"%s\" due to environment variable override (\"%s\")\n", quirks[i].hint_name, quirks[i].hint_value, exe_name, SDL20_getenv(quirks[i].hint_name)); } @@ -1342,8 +1344,8 @@ LoadSDL20(void) if (!okay) { sprintf_fn(loaderror, "SDL2 %d.%d.%d library is too old.", v.major, v.minor, v.patch); } else { - const SDL_bool debug_logging = SDL12Compat_GetHintBoolean("SDL12COMPAT_DEBUG_LOGGING", SDL_FALSE); - if (debug_logging) { + WantDebugLogging = SDL12Compat_GetHintBoolean("SDL12COMPAT_DEBUG_LOGGING", SDL_FALSE); + if (WantDebugLogging) { #if defined(__DATE__) && defined(__TIME__) SDL20_Log("sdl12-compat, built on " __DATE__ " at " __TIME__ ", talking to SDL2 %d.%d.%d", v.major, v.minor, v.patch); #else @@ -2049,7 +2051,9 @@ Init12VidModes(void) int i, j; SDL12_Rect prev_mode = { 0, 0, 0, 0 }, current_mode = { 0, 0, 0, 0 }; /* We only want to enable fake modes if OpenGL Logical Scaling is enabled. */ - SDL_bool use_fake_modes = SDL12Compat_GetHintBoolean("SDL12COMPAT_OPENGL_SCALING", SDL_TRUE); + const SDL_bool use_fake_modes = SDL12Compat_GetHintBoolean("SDL12COMPAT_OPENGL_SCALING", SDL_TRUE); + + WantOpenGLScaling = use_fake_modes; if (VideoModesCount > 0) { return 0; /* already did this. */ @@ -2191,9 +2195,12 @@ static int Init12Video(void) { const char *driver = SDL20_GetCurrentVideoDriver(); + const char *scale_method_env = SDL12Compat_GetHint("SDL12COMPAT_SCALE_METHOD"); SDL_DisplayMode mode; int i; + WantScaleMethodNearest = (scale_method_env && !SDL20_strcmp(scale_method_env, "nearest")) ? SDL_TRUE : SDL_FALSE; + /* Only override this if the env var is set, as the default is platform-specific. */ TranslateKeyboardLayout = SDL12Compat_GetHintBoolean("SDL12COMPAT_USE_KEYBOARD_LAYOUT", TranslateKeyboardLayout); @@ -5626,6 +5633,7 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12) SDL_DisplayMode dmode; Uint32 fullscreen_flags20 = 0; Uint32 appfmt; + const char *vsync_env = SDL12Compat_GetHint("SDL12COMPAT_SYNC_TO_VBLANK"); float window_size_scaling = SDL12Compat_GetHintFloat("SDL12COMPAT_WINDOW_SCALING", 1.0f); SDL_bool use_gl_scaling = SDL_FALSE; SDL_bool use_highdpi = SDL_TRUE; @@ -5648,7 +5656,7 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12) UT2004 is known to use FBOs with SDL 1.2, and I assume idTech 4 games (Doom 3, Quake 4, Prey) do as well. */ - use_gl_scaling = SDL12Compat_GetHintBoolean("SDL12COMPAT_OPENGL_SCALING", SDL_TRUE); + use_gl_scaling = WantOpenGLScaling; /* default use_highdpi to false for OpenGL windows when not using OpenGL scaling as legacy OpenGL applications are unlikely to support @@ -5888,7 +5896,6 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12) } if (flags12 & SDL12_OPENGL) { - const char *vsync_env = SDL12Compat_GetHint("SDL12COMPAT_SYNC_TO_VBLANK"); SDL_assert(!VideoTexture20); /* either a new window or we destroyed all this */ SDL_assert(!VideoRenderer20); @@ -5952,11 +5959,8 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12) } else { /* always use a renderer for non-OpenGL windows. */ - const char *vsync_env = SDL12Compat_GetHint("SDL12COMPAT_SYNC_TO_VBLANK"); const char *old_scale_quality = SDL20_GetHint(SDL_HINT_RENDER_SCALE_QUALITY); - const char *scale_method_env = SDL12Compat_GetHint("SDL12COMPAT_SCALE_METHOD"); const SDL_bool want_vsync = (vsync_env && SDL20_atoi(vsync_env)) ? SDL_TRUE : SDL_FALSE; - const SDL_bool want_nearest = (scale_method_env && !SDL20_strcmp(scale_method_env, "nearest"))? SDL_TRUE : SDL_FALSE; SDL_RendererInfo rinfo; SDL_assert(!VideoGLContext20); /* either a new window or we destroyed all this */ if (!VideoRenderer20 && want_vsync) { @@ -5995,7 +5999,7 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12) VideoConvertSurface20 = NULL; } - SDL20_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, want_nearest?"0":"1"); + SDL20_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, WantScaleMethodNearest ? "0" : "1"); VideoTexture20 = SDL20_CreateTexture(VideoRenderer20, rinfo.texture_formats[0], SDL_TEXTUREACCESS_STREAMING, width, height); SDL20_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, old_scale_quality); if (!VideoTexture20) { @@ -7524,8 +7528,6 @@ SDL_GL_SwapBuffers(void) if (OpenGLLogicalScalingFBO != 0) { const GLboolean has_scissor = OpenGLFuncs.glIsEnabled(GL_SCISSOR_TEST); - const char *scale_method_env = SDL12Compat_GetHint("SDL12COMPAT_SCALE_METHOD"); - const SDL_bool want_nearest = (scale_method_env && !SDL20_strcmp(scale_method_env, "nearest"))? SDL_TRUE : SDL_FALSE; int physical_w, physical_h; GLfloat clearcolor[4]; SDL_Rect dstrect; @@ -7556,7 +7558,7 @@ SDL_GL_SwapBuffers(void) OpenGLFuncs.glClear(GL_COLOR_BUFFER_BIT); OpenGLFuncs.glBlitFramebuffer(0, 0, OpenGLLogicalScalingWidth, OpenGLLogicalScalingHeight, dstrect.x, dstrect.y, dstrect.x + dstrect.w, dstrect.y + dstrect.h, - GL_COLOR_BUFFER_BIT, want_nearest?GL_NEAREST:GL_LINEAR); + GL_COLOR_BUFFER_BIT, WantScaleMethodNearest ? GL_NEAREST : GL_LINEAR); OpenGLFuncs.glBindFramebuffer(GL_FRAMEBUFFER, 0); SDL20_GL_SwapWindow(VideoWindow20); OpenGLFuncs.glClearColor(clearcolor[0], clearcolor[1], clearcolor[2], clearcolor[3]); From 234e376f1ce1cd6f5f0e56662f1567bf3e75581d Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 8 Sep 2022 11:20:02 -0400 Subject: [PATCH 331/606] docs: document when hints are checked. Fixes #188. --- README.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 2c120bf93..fc5e47516 100644 --- a/README.md +++ b/README.md @@ -153,24 +153,24 @@ plans to tweak these values on the fly!) The available options are: -- SDL12COMPAT_DEBUG_LOGGING: +- SDL12COMPAT_DEBUG_LOGGING: (checked at startup) If enabled, print debugging messages to stderr. These messages are mostly useful to developers, or when trying to track down a specific bug. -- SDL12COMPAT_FAKE_CDROM_PATH: +- SDL12COMPAT_FAKE_CDROM_PATH: (checked during SDL_Init) A path to a directory containing MP3 files (named trackXX.mp3, where XX is a two-digit track number) to be used by applications which play CD audio. Using an absolute path is recommended: relative paths are not guaranteed to work correctly. -- SDL12COMPAT_OPENGL_SCALING: +- SDL12COMPAT_OPENGL_SCALING: (checked during SDL_Init) Enables scaling of OpenGL applications to the current desktop resolution. If disabled, applications can change the real screen resolution. This option is enabled by default, but not all applications are compatible with it: try changing this if you can only see a black screen. -- SDL12COMPAT_FIX_BORDERLESS_FS_WIN: +- SDL12COMPAT_FIX_BORDERLESS_FS_WIN: (checked during SDL_SetVideoMode) Enables turning borderless windows at the desktop resolution into actual fullscreen windows (so they'll go into a separate space on macOS and properly hide dock windows on other desktop environments, etc). @@ -179,23 +179,23 @@ The available options are: so it can be manually disabled, in case this causes some negative result we haven't anticipated. -- SDL12COMPAT_SCALE_METHOD: +- SDL12COMPAT_SCALE_METHOD: (checked during SDL_Init) Choose the scaling method used when applications render at a non-native resolution. The options are `nearest`, for nearest-neighbour sampling (more pixelated) and `linear` for bilinear sampling (blurrier). -- SDL12COMPAT_HIGHDPI: +- SDL12COMPAT_HIGHDPI: (checked during SDL_SetVideoMode) Advertise the application as supporting high-DPI displays. Enabling this will usually result in sharper graphics, but on some applications text and other elements may become very small. -- SDL12COMPAT_SYNC_TO_VBLANK: +- SDL12COMPAT_SYNC_TO_VBLANK: (checked during SDL_SetVideoMode) Force the application to sync (or not sync) to the vertical blanking interval (VSync). When enabled, this will cap the application's framerate to the screen's refresh rate (and may resolve issues with screen tearing). -- SDL12COMPAT_USE_KEYBOARD_LAYOUT: +- SDL12COMPAT_USE_KEYBOARD_LAYOUT: (checked during SDL_Init) Make all keyboard input take the current keyboard layout into account. This may need to be disabled for applications which provide their own keyboard layout support, or if the position of the keys on the keyboard @@ -203,7 +203,7 @@ The available options are: (in most applications) will take the keyboard layout into account regardless of this option. -- SDL12COMPAT_USE_GAME_CONTROLLERS: +- SDL12COMPAT_USE_GAME_CONTROLLERS: (checked during SDL_Init) Use SDL2's higher-level Game Controller API to expose joysticks instead of its lower-level joystick API. The benefit of this is that you can exert more control over arbitrary hardware (deadzones, button mapping, device @@ -215,7 +215,7 @@ The available options are: use this hint. If there is no known game controller mapping for a joystick, and this hint is in use, it will not be listed as an availble device. -- SDL12COMPAT_WINDOW_SCALING: +- SDL12COMPAT_WINDOW_SCALING: (checked during SDL_SetVideoMode) When creating non-fullscreen, non-resizable windows, use this variable to size the window differently. If, for example, you have a 4K monitor and the game is running in a window the size of a postage stamp, you might set this @@ -228,7 +228,7 @@ The available options are: will create the window at the originally-requested size. If this variable isn't specified, it defaults to 1.0 (no scaling). -- SDL_MOUSE_RELATIVE_SCALING: +- SDL_MOUSE_RELATIVE_SCALING: (checked during SDL_SetVideoMode) If enabled, relative mouse motion is scaled when the application is running at a non-native resolution. This may be required with some applications which use their own mouse cursors. See also: From 671cd3feca6bacc75b9e05ce2e31f7f90c6dda55 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 8 Sep 2022 11:20:27 -0400 Subject: [PATCH 332/606] hints: Don't double-set SDL_VIDEODRIVER. sdl12-compat hints are always environment variables now, so no need to force the environment variable now; it's already there. --- src/SDL12_compat.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 3265965c8..5fc0bf20b 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -2309,12 +2309,6 @@ SDL_InitSubSystem(Uint32 sdl12flags) sdl12_compat_macos_init(); #endif - /* Some applications need to force a specific videodriver. */ - forcevideodrv = SDL12Compat_GetHint("SDL_VIDEODRIVER"); - if (forcevideodrv) { - SDL20_setenv("SDL_VIDEODRIVER", forcevideodrv, 1); - } - /* note that currently we ignore SDL12_INIT_NOPARACHUTE, since there _isn't_ a parachute in SDL2, and mostly it was meant to deal with X11's XVidMode leaving the display resolution busted if the app From fe3810fda122599b6227fb18002627326f6da69b Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 8 Sep 2022 11:21:42 -0400 Subject: [PATCH 333/606] init: Quirks were only applied if debug logging was enabled. :O --- src/SDL12_compat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 5fc0bf20b..f568b2191 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1351,8 +1351,8 @@ LoadSDL20(void) #else SDL20_Log("sdl12-compat, talking to SDL2 %d.%d.%d", v.major, v.minor, v.patch); #endif - SDL12Compat_ApplyQuirks(); /* Apply and maybe print a list of any enabled quirks. */ } + SDL12Compat_ApplyQuirks(); /* Apply and maybe print a list of any enabled quirks. */ } } if (!okay) { From 05947b551ca60aa7b2fb5645eaee113af70e8ba6 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 8 Sep 2022 11:22:33 -0400 Subject: [PATCH 334/606] Removed unused variable. --- src/SDL12_compat.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index f568b2191..d06e60d08 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -2290,7 +2290,6 @@ DECLSPEC12 int SDLCALL SDL_InitSubSystem(Uint32 sdl12flags) { Uint32 sdl20flags = 0; - const char *forcevideodrv; int rc; #ifdef __WINDOWS__ From 300990c5a7d51254c1b65c1e1ad33bd4f2b7609c Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 8 Sep 2022 13:17:33 -0400 Subject: [PATCH 335/606] Revert "syswm: The magic SDL_SysWMinfo2on12 hack reports the `SDL_Window *` now, too." This reverts commit f0199bdb25e2a1483eee7a3dccb95565323dd0b4. --- include/SDL/SDL_syswm.h | 1 - src/SDL12_compat.c | 2 -- test/testsyswm2on12.c | 1 - 3 files changed, 4 deletions(-) diff --git a/include/SDL/SDL_syswm.h b/include/SDL/SDL_syswm.h index 80865d1a2..2add7d9b7 100644 --- a/include/SDL/SDL_syswm.h +++ b/include/SDL/SDL_syswm.h @@ -134,7 +134,6 @@ typedef struct SDL_SysWMinfo2on12 void *data6; void *data7; void *data8; - void *sdl2_window; /* this is the SDL2 SDL_Window */ } SDL_SysWMinfo2on12; extern DECLSPEC int SDLCALL SDL_GetWMInfo(SDL_SysWMinfo *info); diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index d06e60d08..863b95b24 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -650,7 +650,6 @@ typedef struct SDL12_SysWMinfo2on12 void *data6; void *data7; void *data8; - void *sdl2_window; } SDL12_SysWMinfo2on12; @@ -7045,7 +7044,6 @@ SDL_GetWMInfo(SDL12_SysWMinfo *info12) SDL_zerop(wminfo2); SDL20_memcpy(&wminfo2->version, &info20.version, sizeof (wminfo2->version)); wminfo2->subsystem = (Uint32) info20.subsystem; /* these do not map to SDL 1.2 values! You're on your own! */ - wminfo2->sdl2_window = VideoWindow20; switch (info20.subsystem) { #if defined(SDL_VIDEO_DRIVER_WINDOWS) diff --git a/test/testsyswm2on12.c b/test/testsyswm2on12.c index ee2ffa099..73b000df8 100644 --- a/test/testsyswm2on12.c +++ b/test/testsyswm2on12.c @@ -105,7 +105,6 @@ int main(int argc, char **argv) printf("data6: %p\n", syswm_info.data6); printf("data7: %p\n", syswm_info.data7); printf("data8: %p\n", syswm_info.data8); - printf("sdl2_window: %p\n", syswm_info.sdl2_window); } SDL_Quit(); From 38717f024ff828525a5a33bca7230796b34598c2 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 8 Sep 2022 13:19:32 -0400 Subject: [PATCH 336/606] Revert "syswm: Added a magic hack so apps can access actual SDL2 SysWM information." This reverts commit b13166f31a1d1b315744e6cc45901173d99590c7. --- CMakeLists.txt | 1 - include/SDL/SDL_syswm.h | 16 ----- src/SDL12_compat.c | 128 +--------------------------------------- test/README | 1 - test/testsyswm2on12.c | 113 ----------------------------------- 5 files changed, 1 insertion(+), 258 deletions(-) delete mode 100644 test/testsyswm2on12.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 41c72e992..3c506c13c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -218,7 +218,6 @@ if(SDL12TESTS) test_program(torturethread "test/torturethread.c") test_program(testdyngl "test/testdyngl.c") test_program(testgl "test/testgl.c") - test_program(testsyswm2on12 "test/testsyswm2on12.c") if(OPENGL_FOUND) if(CMAKE_VERSION VERSION_LESS 3.10 OR NOT OPENGL_opengl_LIBRARY) target_link_libraries(testgl ${OPENGL_gl_LIBRARY}) diff --git a/include/SDL/SDL_syswm.h b/include/SDL/SDL_syswm.h index 2add7d9b7..007618d10 100644 --- a/include/SDL/SDL_syswm.h +++ b/include/SDL/SDL_syswm.h @@ -120,22 +120,6 @@ real SDL-1.2 available to you. */ #include "begin_code.h" -/* SPECIAL CASE FOR SDL12-COMPAT: if version.major == 2, we'll fill in this struct with the native window handle. */ -/* This is not part of the real 1.2 API! */ -typedef struct SDL_SysWMinfo2on12 -{ - SDL_version version; - Uint32 subsystem; - void *data1; - void *data2; - void *data3; - void *data4; - void *data5; - void *data6; - void *data7; - void *data8; -} SDL_SysWMinfo2on12; - extern DECLSPEC int SDLCALL SDL_GetWMInfo(SDL_SysWMinfo *info); #include "close_code.h" diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 863b95b24..9c0d81543 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -636,23 +636,6 @@ typedef struct SDL12_SysWMinfo #endif } SDL12_SysWMinfo; -/* SPECIAL CASE FOR SDL12-COMPAT: if version.major == 2, we'll fill in this struct with the native window handle. */ -/* This is not part of the real 1.2 API! */ -typedef struct SDL12_SysWMinfo2on12 -{ - SDL_version version; - Uint32 subsystem; - void *data1; - void *data2; - void *data3; - void *data4; - void *data5; - void *data6; - void *data7; - void *data8; -} SDL12_SysWMinfo2on12; - - typedef enum { SDL12_NOEVENT = 0, @@ -6995,10 +6978,9 @@ SDL_GetWMInfo(SDL12_SysWMinfo *info12) SDL_SysWMinfo info20; SDL_bool temp_window = SDL_FALSE; SDL_Window *win20 = VideoWindow20; - const int do_2on12 = ((info12->version.major == 2) && (info12->version.minor == 0) && (info12->version.major == 2) && (info12->version.patch == 0)); int rc; - if ((info12->version.major > 1) && !do_2on12) { + if (info12->version.major > 1) { SDL20_SetError("Requested version is unsupported"); return 0; /* some programs only test against 0, not -1 */ } else if (!SupportSysWM) { @@ -7038,114 +7020,6 @@ SDL_GetWMInfo(SDL12_SysWMinfo *info12) return 0; /* some programs only test against 0, not -1 */ } - /* SPECIAL CASE FOR SDL12-COMPAT: if version.major == 2, we'll fill in this struct with the native window handle. */ - if (do_2on12) { - SDL12_SysWMinfo2on12 *wminfo2 = (SDL12_SysWMinfo2on12 *) info12; - SDL_zerop(wminfo2); - SDL20_memcpy(&wminfo2->version, &info20.version, sizeof (wminfo2->version)); - wminfo2->subsystem = (Uint32) info20.subsystem; /* these do not map to SDL 1.2 values! You're on your own! */ - - switch (info20.subsystem) { - #if defined(SDL_VIDEO_DRIVER_WINDOWS) - case SDL_SYSWM_WINDOWS: - wminfo2->data1 = (void *) info20.info.win.window; - wminfo2->data2 = (void *) info20.info.win.hdc; - wminfo2->data3 = (void *) info20.info.win.hinstance; - break; - #endif - - #if defined(SDL_VIDEO_DRIVER_WINRT) - case SDL_SYSWM_WINRT: - wminfo2->data1 = (void *) info20.info.winrt.window; - break; - #endif - - #if defined(SDL_VIDEO_DRIVER_X11) - case SDL_SYSWM_X11: - wminfo2->data1 = (void *) info20.info.x11.display; - wminfo2->data2 = (void *) info20.info.x11.window; - break; - #endif - - #if defined(SDL_VIDEO_DRIVER_DIRECTFB) - case SDL_SYSWM_DIRECTFB: - wminfo2->data1 = (void *) info20.info.dfb.dfb; - wminfo2->data2 = (void *) info20.info.dfb.window; - wminfo2->data3 = (void *) info20.info.dfb.surface; - break; - #endif - - #if defined(SDL_VIDEO_DRIVER_COCOA) - case SDL_SYSWM_COCOA: - wminfo2->data1 = (void *) info20.info.cocoa.window; - break; - #endif - - #if defined(SDL_VIDEO_DRIVER_UIKIT) - case SDL_SYSWM_UIKIT: - wminfo2->data1 = (void *) info20.info.uikit.window; - wminfo2->data2 = (void *) info20.info.uikit.framebuffer; - wminfo2->data3 = (void *) info20.info.uikit.colorbuffer; - wminfo2->data4 = (void *) info20.info.uikit.resolveFramebuffer; - break; - #endif - - #if defined(SDL_VIDEO_DRIVER_WAYLAND) - case SDL_SYSWM_WAYLAND: - wminfo2->data1 = (void *) info20.info.wl.display; - wminfo2->data2 = (void *) info20.info.wl.surface; - wminfo2->data3 = (void *) info20.info.wl.shell_surface; - wminfo2->data4 = (void *) info20.info.wl.egl_window; - wminfo2->data5 = (void *) info20.info.wl.xdg_surface; - wminfo2->data6 = (void *) info20.info.wl.xdg_toplevel; - wminfo2->data7 = (void *) info20.info.wl.xdg_popup; - wminfo2->data8 = (void *) info20.info.wl.xdg_positioner; - break; - #endif - - #if defined(SDL_VIDEO_DRIVER_MIR) /* no longer available, left for API/ABI compatibility. Remove in 2.1! */ - case SDL_SYSWM_MIR: - wminfo2->data1 = (void *) info20.info.mir.connection; - wminfo2->data2 = (void *) info20.info.mir.surface; - break; - #endif - - #if defined(SDL_VIDEO_DRIVER_ANDROID) - case SDL_SYSWM_ANDROID: - wminfo2->data1 = (void *) info20.info.android.window; - wminfo2->data2 = (void *) info20.info.android.surface; - break; - #endif - - #if defined(SDL_VIDEO_DRIVER_OS2) - case SDL_SYSWM_OS2: - wminfo2->data1 = (void *) info20.info.os2.hwnd; - wminfo2->data2 = (void *) info20.info.os2.hwndFrame; - break; - #endif - - #if defined(SDL_VIDEO_DRIVER_VIVANTE) - case SDL_SYSWM_VIVANTE: - wminfo2->data1 = (void *) info20.info.vivante.display; - wminfo2->data2 = (void *) info20.info.vivante.window; - break; - #endif - - #if defined(SDL_VIDEO_DRIVER_KMSDRM) - case SDL_SYSWM_KMSDRM: - wminfo2->data1 = (void *) (size_t) info20.info.kmsdrm.dev_index; - wminfo2->data2 = (void *) (size_t) info20.info.kmsdrm.drm_fd; - wminfo2->data3 = (void *) (size_t) info20.info.kmsdrm.gbm_dev; - break; - #endif - - default: - return 0; - } - - return 1; - } - #if defined(SDL_VIDEO_DRIVER_WINDOWS) SDL_assert(info20.subsystem == SDL_SYSWM_WINDOWS); info12->window = temp_window ? 0 : info20.info.win.window; diff --git a/test/README b/test/README index a77450a7b..e158b4e42 100644 --- a/test/README +++ b/test/README @@ -33,4 +33,3 @@ These are test programs for the SDL library: testwm Test window manager -- title, icon, events threadwin Test multi-threaded event handling torturethread Simple test for thread creation/destruction - testsyswm2on12 Simple test for SDL_SysWM2on12 compatibility magic. \ No newline at end of file diff --git a/test/testsyswm2on12.c b/test/testsyswm2on12.c deleted file mode 100644 index 73b000df8..000000000 --- a/test/testsyswm2on12.c +++ /dev/null @@ -1,113 +0,0 @@ -/* this isn't a classic SDL 1.2 test program, this tests a little - compatibility magic that only exists in sdl12-compat. */ - -#include -#include - -#include "SDL.h" -#include "SDL_syswm.h" - -/* so this will compile with classic 1.2 headers... */ -#ifndef SDL12_COMPAT_HEADERS -#include "begin_code.h" -typedef struct SDL_SysWMinfo2on12 -{ - SDL_version version; - Uint32 subsystem; - void *data1; - void *data2; - void *data3; - void *data4; - void *data5; - void *data6; - void *data7; - void *data8; -} SDL_SysWMinfo2on12; -#include "end_code.h" -#endif - -typedef enum -{ - SDL20_SYSWM_UNKNOWN, - SDL20_SYSWM_WINDOWS, - SDL20_SYSWM_X11, - SDL20_SYSWM_DIRECTFB, - SDL20_SYSWM_COCOA, - SDL20_SYSWM_UIKIT, - SDL20_SYSWM_WAYLAND, - SDL20_SYSWM_MIR, - SDL20_SYSWM_WINRT, - SDL20_SYSWM_ANDROID, - SDL20_SYSWM_VIVANTE, - SDL20_SYSWM_OS2, - SDL20_SYSWM_HAIKU, - SDL20_SYSWM_KMSDRM, - SDL20_SYSWM_RISCOS -} SDL20_SYSWM_TYPE; - -static const char * -subsystem_name(const Uint32 typ) -{ - static char unrecognized[64]; - switch ((SDL20_SYSWM_TYPE) typ) { - case SDL20_SYSWM_UNKNOWN: return "Unknown"; - case SDL20_SYSWM_WINDOWS: return "Windows"; - case SDL20_SYSWM_X11: return "X11"; - case SDL20_SYSWM_DIRECTFB: return "DirectFB"; - case SDL20_SYSWM_COCOA: return "Cocoa"; - case SDL20_SYSWM_UIKIT: return "UIKit"; - case SDL20_SYSWM_WAYLAND: return "Wayland"; - case SDL20_SYSWM_MIR: return "Mir"; - case SDL20_SYSWM_WINRT: return "WinRT"; - case SDL20_SYSWM_ANDROID: return "Android"; - case SDL20_SYSWM_VIVANTE: return "Vivante"; - case SDL20_SYSWM_OS2: return "OS/2"; - case SDL20_SYSWM_HAIKU: return "Haiku"; - case SDL20_SYSWM_KMSDRM: return "KMSDRM"; - case SDL20_SYSWM_RISCOS: return "RiscOS"; - default: break; - } - - snprintf(unrecognized, sizeof (unrecognized), "Unrecognized (%d)", (int) typ); - return unrecognized; -} - -int main(int argc, char **argv) -{ - SDL_SysWMinfo2on12 syswm_info; - - if (SDL_Init(SDL_INIT_VIDEO) < 0) { - fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError()); - return 1; - } - - if (SDL_SetVideoMode(640, 480, 32, 0) == NULL) { - fprintf(stderr, "Couldn't create an SDL window: %s\n", SDL_GetError()); - SDL_Quit(); - return 1; - } - - SDL_memset(&syswm_info, '\0', sizeof (syswm_info)); - syswm_info.version.major = 2; /* this triggers magic in sdl12-compat */ - - /* obviously this should fail with classic SDL 1.2. */ - if (SDL_GetWMInfo((SDL_SysWMinfo *) &syswm_info) != 1) { - fprintf(stderr, "Failed to get syswm 2on12 info: %s\n", SDL_GetError()); - } else { - printf("SysWM2on12 info:\n"); - printf("Version: %d.%d.%d\n", syswm_info.version.major, syswm_info.version.minor, syswm_info.version.patch); - printf("Subsystem: %s\n", subsystem_name(syswm_info.subsystem)); - printf("data1: %p\n", syswm_info.data1); - printf("data2: %p\n", syswm_info.data2); - printf("data3: %p\n", syswm_info.data3); - printf("data4: %p\n", syswm_info.data4); - printf("data5: %p\n", syswm_info.data5); - printf("data6: %p\n", syswm_info.data6); - printf("data7: %p\n", syswm_info.data7); - printf("data8: %p\n", syswm_info.data8); - } - - SDL_Quit(); - return 0; -} - From 52459d2b8a68f77afda504da4e93887c8ed1fbd0 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 8 Sep 2022 13:20:54 -0400 Subject: [PATCH 337/606] Simplified the SDL_GetWMInfo-requests-SDL2-details code. This patch written by @kjliew. Fixes #186. --- include/SDL/SDL_syswm.h | 2 +- src/SDL12_compat.c | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/include/SDL/SDL_syswm.h b/include/SDL/SDL_syswm.h index 007618d10..4321a07a0 100644 --- a/include/SDL/SDL_syswm.h +++ b/include/SDL/SDL_syswm.h @@ -109,7 +109,7 @@ real SDL-1.2 available to you. */ typedef struct SDL_SysWMinfo { SDL_version version; - int data; + void *data; } SDL_SysWMinfo; # include "close_code.h" diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 9c0d81543..2a379826f 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -6981,6 +6981,16 @@ SDL_GetWMInfo(SDL12_SysWMinfo *info12) int rc; if (info12->version.major > 1) { + if (info12->version.major == 2) { +#if defined(SDL_VIDEO_DRIVER_WINDOWS) + info12->window = (HWND)VideoWindow20; +#elif defined(SDL_VIDEO_DRIVER_X11) + info12->info.x11.gfxdisplay = (Display *)VideoWindow20; +#else + info12->data = (void *)VideoWindow20; +#endif + return 1; + } SDL20_SetError("Requested version is unsupported"); return 0; /* some programs only test against 0, not -1 */ } else if (!SupportSysWM) { From 0708d1e9a774fc2dca04af9805e660b1e53ebc24 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 8 Sep 2022 11:14:30 -0700 Subject: [PATCH 338/606] Fixed ABI change in https://github.com/libsdl-org/sdl12-compat/commit/52459d2b8a68f77afda504da4e93887c8ed1fbd0 --- include/SDL/SDL_syswm.h | 7 ++++++- src/SDL12_compat.c | 9 ++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/include/SDL/SDL_syswm.h b/include/SDL/SDL_syswm.h index 4321a07a0..c96d7865a 100644 --- a/include/SDL/SDL_syswm.h +++ b/include/SDL/SDL_syswm.h @@ -32,6 +32,8 @@ real SDL-1.2 available to you. */ #ifndef SDL_PROTOTYPES_ONLY +typedef struct SDL_Window SDL_Window; + # if defined(__WIN32__) # ifndef WIN32_LEAN_AND_MEAN # define WIN32_LEAN_AND_MEAN @@ -53,6 +55,7 @@ real SDL-1.2 available to you. */ SDL_version version; HWND window; HGLRC hglrc; + SDL_Window *sdl2_window; } SDL_SysWMinfo; # include "close_code.h" @@ -92,6 +95,7 @@ real SDL-1.2 available to you. */ Display *gfxdisplay; } x11; } info; + SDL_Window *sdl2_window; } SDL_SysWMinfo; # include "close_code.h" @@ -109,7 +113,8 @@ real SDL-1.2 available to you. */ typedef struct SDL_SysWMinfo { SDL_version version; - void *data; + int data; + SDL_Window *sdl2_window; } SDL_SysWMinfo; # include "close_code.h" diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 2a379826f..fa19762cf 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -634,6 +634,7 @@ typedef struct SDL12_SysWMinfo #else int data; /* unused at the moment. */ #endif + SDL_Window *sdl2_window; } SDL12_SysWMinfo; typedef enum @@ -6982,13 +6983,7 @@ SDL_GetWMInfo(SDL12_SysWMinfo *info12) if (info12->version.major > 1) { if (info12->version.major == 2) { -#if defined(SDL_VIDEO_DRIVER_WINDOWS) - info12->window = (HWND)VideoWindow20; -#elif defined(SDL_VIDEO_DRIVER_X11) - info12->info.x11.gfxdisplay = (Display *)VideoWindow20; -#else - info12->data = (void *)VideoWindow20; -#endif + info12->sdl2_window = VideoWindow20; return 1; } SDL20_SetError("Requested version is unsupported"); From 7e99b60d2f70bd348137f0c4ad054011afd71fbc Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 8 Sep 2022 15:37:52 -0700 Subject: [PATCH 339/606] Revert "Fixed ABI change in https://github.com/libsdl-org/sdl12-compat/commit/52459d2b8a68f77afda504da4e93887c8ed1fbd0" This reverts commit 0708d1e9a774fc2dca04af9805e660b1e53ebc24. There were concerns with changing the size of SDL_SysWMinfo so we're not going to go that route. --- include/SDL/SDL_syswm.h | 7 +------ src/SDL12_compat.c | 9 +++++++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/include/SDL/SDL_syswm.h b/include/SDL/SDL_syswm.h index c96d7865a..4321a07a0 100644 --- a/include/SDL/SDL_syswm.h +++ b/include/SDL/SDL_syswm.h @@ -32,8 +32,6 @@ real SDL-1.2 available to you. */ #ifndef SDL_PROTOTYPES_ONLY -typedef struct SDL_Window SDL_Window; - # if defined(__WIN32__) # ifndef WIN32_LEAN_AND_MEAN # define WIN32_LEAN_AND_MEAN @@ -55,7 +53,6 @@ typedef struct SDL_Window SDL_Window; SDL_version version; HWND window; HGLRC hglrc; - SDL_Window *sdl2_window; } SDL_SysWMinfo; # include "close_code.h" @@ -95,7 +92,6 @@ typedef struct SDL_Window SDL_Window; Display *gfxdisplay; } x11; } info; - SDL_Window *sdl2_window; } SDL_SysWMinfo; # include "close_code.h" @@ -113,8 +109,7 @@ typedef struct SDL_Window SDL_Window; typedef struct SDL_SysWMinfo { SDL_version version; - int data; - SDL_Window *sdl2_window; + void *data; } SDL_SysWMinfo; # include "close_code.h" diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index fa19762cf..2a379826f 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -634,7 +634,6 @@ typedef struct SDL12_SysWMinfo #else int data; /* unused at the moment. */ #endif - SDL_Window *sdl2_window; } SDL12_SysWMinfo; typedef enum @@ -6983,7 +6982,13 @@ SDL_GetWMInfo(SDL12_SysWMinfo *info12) if (info12->version.major > 1) { if (info12->version.major == 2) { - info12->sdl2_window = VideoWindow20; +#if defined(SDL_VIDEO_DRIVER_WINDOWS) + info12->window = (HWND)VideoWindow20; +#elif defined(SDL_VIDEO_DRIVER_X11) + info12->info.x11.gfxdisplay = (Display *)VideoWindow20; +#else + info12->data = (void *)VideoWindow20; +#endif return 1; } SDL20_SetError("Requested version is unsupported"); From e7cf61ec93f0968dc94ae48c42181b057e74eabf Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 8 Sep 2022 15:47:35 -0700 Subject: [PATCH 340/606] Added a special API function to get access to the SDL 2.0 window Fixes https://github.com/libsdl-org/sdl12-compat/issues/186 --- include/SDL/SDL_syswm.h | 3 +++ src/SDL12_compat.c | 11 +++++++++++ test/testwm.c | 3 +++ 3 files changed, 17 insertions(+) diff --git a/include/SDL/SDL_syswm.h b/include/SDL/SDL_syswm.h index 4321a07a0..13ee52b1e 100644 --- a/include/SDL/SDL_syswm.h +++ b/include/SDL/SDL_syswm.h @@ -122,6 +122,9 @@ real SDL-1.2 available to you. */ extern DECLSPEC int SDLCALL SDL_GetWMInfo(SDL_SysWMinfo *info); +typedef struct SDL_Window SDL_Window; +extern DECLSPEC SDL_Window * SDLCALL SDL12COMPAT_GetWindow(void); + #include "close_code.h" #endif diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 2a379826f..2ce6eeb63 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -7057,6 +7057,12 @@ SDL_GetWMInfo(SDL12_SysWMinfo *info12) return 1; } +DECLSPEC12 SDL_Window * SDLCALL +SDL12COMPAT_GetWindow(void) +{ + return VideoWindow20; +} + DECLSPEC12 SDL12_Overlay * SDLCALL SDL_CreateYUVOverlay(int w, int h, Uint32 format12, SDL12_Surface *display12) { @@ -7299,6 +7305,11 @@ SDL_GL_GetProcAddress(const char *sym) if ((SDL20_strcmp(sym, "glCopyTexSubImage3D") == 0)) { return (void *) glCopyTexSubImage3D_shim_for_scaling; } + + /* this function is specific to the shim library */ + if ((SDL20_strcmp(sym, "SDL12COMPAT_GetWindow") == 0)) { + return (void *) SDL12COMPAT_GetWindow; + } return SDL20_GL_GetProcAddress(sym); } diff --git a/test/testwm.c b/test/testwm.c index 04861562e..ced2981d8 100644 --- a/test/testwm.c +++ b/test/testwm.c @@ -458,6 +458,9 @@ int main(int argc, char *argv[]) printf("Generic syswm info: data=%X\n", syswm_info.data); #endif } +#if SDL_COMPILEDVERSION >= SDL_VERSIONNUM(1, 2, 54) + printf("SDL 2.0 window: %p\n", SDL12COMPAT_GetWindow()); +#endif } SDL_EventState(SDL_SYSWMEVENT, SDL_ENABLE); #endif From c336f9cdd111ae6c26e3394f53794959436a0b2d Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 8 Sep 2022 15:51:23 -0700 Subject: [PATCH 341/606] Revert "Simplified the SDL_GetWMInfo-requests-SDL2-details code." This reverts commit 52459d2b8a68f77afda504da4e93887c8ed1fbd0. --- include/SDL/SDL_syswm.h | 2 +- src/SDL12_compat.c | 10 ---------- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/include/SDL/SDL_syswm.h b/include/SDL/SDL_syswm.h index 13ee52b1e..b8258c29d 100644 --- a/include/SDL/SDL_syswm.h +++ b/include/SDL/SDL_syswm.h @@ -109,7 +109,7 @@ real SDL-1.2 available to you. */ typedef struct SDL_SysWMinfo { SDL_version version; - void *data; + int data; } SDL_SysWMinfo; # include "close_code.h" diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 2ce6eeb63..4710ad970 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -6981,16 +6981,6 @@ SDL_GetWMInfo(SDL12_SysWMinfo *info12) int rc; if (info12->version.major > 1) { - if (info12->version.major == 2) { -#if defined(SDL_VIDEO_DRIVER_WINDOWS) - info12->window = (HWND)VideoWindow20; -#elif defined(SDL_VIDEO_DRIVER_X11) - info12->info.x11.gfxdisplay = (Display *)VideoWindow20; -#else - info12->data = (void *)VideoWindow20; -#endif - return 1; - } SDL20_SetError("Requested version is unsupported"); return 0; /* some programs only test against 0, not -1 */ } else if (!SupportSysWM) { From 7b67acc2be7dbd5802671c7e12d50204de874ba8 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 8 Sep 2022 16:16:02 -0700 Subject: [PATCH 342/606] Fixed returning invalid information for non-X11 video drivers --- src/SDL12_compat.c | 44 ++++++++++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 4710ad970..3bb9445e6 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -7020,26 +7020,34 @@ SDL_GetWMInfo(SDL12_SysWMinfo *info12) return 0; /* some programs only test against 0, not -1 */ } -#if defined(SDL_VIDEO_DRIVER_WINDOWS) - SDL_assert(info20.subsystem == SDL_SYSWM_WINDOWS); - info12->window = temp_window ? 0 : info20.info.win.window; - if (SDL_VERSIONNUM(info12->version.major, info12->version.minor, info12->version.patch) >= SDL_VERSIONNUM(1, 2, 5)) { - info12->hglrc = (HGLRC) VideoGLContext20; +#if defined(_WIN32) + if (info20.subsystem == SDL_SYSWM_WINDOWS) { + info12->window = temp_window ? 0 : info20.info.win.window; + if (SDL_VERSIONNUM(info12->version.major, info12->version.minor, info12->version.patch) >= SDL_VERSIONNUM(1, 2, 5)) { + info12->hglrc = (HGLRC) VideoGLContext20; + } + } else { + SDL20_SetError("No SysWM information available"); + return 0; /* some programs only test against 0, not -1 */ } #elif defined(SDL_VIDEO_DRIVER_X11) - SDL_assert(info20.subsystem == SDL_SYSWM_X11); - info12->subsystem = SDL12_SYSWM_X11; - info12->info.x11.display = info20.info.x11.display; - info12->info.x11.window = temp_window ? 0 : info20.info.x11.window; - if (SDL_VERSIONNUM(info12->version.major, info12->version.minor, info12->version.patch) >= SDL_VERSIONNUM(1, 0, 2)) { - info12->info.x11.fswindow = 0; /* these don't exist in SDL2. */ - info12->info.x11.wmwindow = 0; - } - if (SDL_VERSIONNUM(info12->version.major, info12->version.minor, info12->version.patch) >= SDL_VERSIONNUM(1, 2, 12)) { - info12->info.x11.gfxdisplay = info20.info.x11.display; /* shrug */ - } - info12->info.x11.lock_func = x11_lock_display; /* just no-ops for now */ - info12->info.x11.unlock_func = x11_unlock_display; + if (info20.subsystem == SDL_SYSWM_X11) { + info12->subsystem = SDL12_SYSWM_X11; + info12->info.x11.display = info20.info.x11.display; + info12->info.x11.window = temp_window ? 0 : info20.info.x11.window; + if (SDL_VERSIONNUM(info12->version.major, info12->version.minor, info12->version.patch) >= SDL_VERSIONNUM(1, 0, 2)) { + info12->info.x11.fswindow = 0; /* these don't exist in SDL2. */ + info12->info.x11.wmwindow = 0; + } + if (SDL_VERSIONNUM(info12->version.major, info12->version.minor, info12->version.patch) >= SDL_VERSIONNUM(1, 2, 12)) { + info12->info.x11.gfxdisplay = info20.info.x11.display; /* shrug */ + } + info12->info.x11.lock_func = x11_lock_display; /* just no-ops for now */ + info12->info.x11.unlock_func = x11_unlock_display; + } else { + SDL20_SetError("No SysWM information available"); + return 0; /* some programs only test against 0, not -1 */ + } #else info12->data = 0; /* shrug */ #endif From 1cb01a574ace30b013efb1eef673207e28e99987 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Fri, 9 Sep 2022 12:23:02 +0300 Subject: [PATCH 343/606] added SDL12COMPAT_GetWindow to watcom windows exports file --- src/SDL12.exports | 1 + 1 file changed, 1 insertion(+) diff --git a/src/SDL12.exports b/src/SDL12.exports index 9b49755f9..fdca921d4 100644 --- a/src/SDL12.exports +++ b/src/SDL12.exports @@ -234,3 +234,4 @@ ++'_SDL_HasSSE'.'SDL.dll'.'SDL_HasSSE'.'SDL_HasSSE' ++'_SDL_HasSSE2'.'SDL.dll'.'SDL_HasSSE2'.'SDL_HasSSE2' ++'_SDL_HasAltiVec'.'SDL.dll'.'SDL_HasAltiVec'.'SDL_HasAltiVec' +++'_SDL12COMPAT_GetWindow'.'SDL.dll'.'SDL12COMPAT_GetWindow'.'SDL12COMPAT_GetWindow' From 7df3288587905a224635001ff285a8d621cccb90 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Mon, 12 Sep 2022 20:52:15 -0700 Subject: [PATCH 344/606] Fixed crash if SDL_WM_SetIcon() is passed a NULL icon --- src/SDL12_compat.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 3bb9445e6..ba3112ef5 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -6693,6 +6693,11 @@ SDL_WM_SetIcon(SDL12_Surface *icon12, Uint8 *mask) int bpp; int ret; + /* Make sure we actually have an icon to set */ + if (!icon12) { + return; + } + /* take the mask and zero out those alpha values. */ oldmode = SDL_BLENDMODE_NONE; if (SDL20_GetSurfaceBlendMode(icon12->surface20, &oldmode) < 0) { From 2aa5d0dfb4d94f7c3f6378ccd474d369d48f9d45 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 16 Sep 2022 10:54:53 -0400 Subject: [PATCH 345/606] SDL_version.h: remove hardcoded version numbers. One less thing to update every release. :) Reference Issue #205. --- include/SDL/SDL_version.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/SDL/SDL_version.h b/include/SDL/SDL_version.h index e25fe896f..00b4f64fd 100644 --- a/include/SDL/SDL_version.h +++ b/include/SDL/SDL_version.h @@ -43,13 +43,13 @@ typedef struct SDL_version } SDL_version; #define SDL_VERSION(X) { \ - (X)->major = 1; \ - (X)->minor = 2; \ - (X)->patch = 54; \ + (X)->major = SDL_MAJOR_VERSION; \ + (X)->minor = SDL_MINOR_VERSION; \ + (X)->patch = SDL_PATCHLEVEL; \ } #define SDL_VERSIONNUM(X, Y, Z) ((X)*1000 + (Y)*100 + (Z)) -#define SDL_COMPILEDVERSION SDL_VERSIONNUM(1, 2, 54) +#define SDL_COMPILEDVERSION SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) #define SDL_VERSION_ATLEAST(X, Y, Z) (SDL_COMPILEDVERSION >= SDL_VERSIONNUM(X, Y, Z)) extern DECLSPEC const SDL_version * SDLCALL SDL_Linked_Version(void); From fe114a1e3b024083de61b6df3595c7e8137899a6 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 16 Sep 2022 11:02:14 -0400 Subject: [PATCH 346/606] update_version.sh: Added a script to automate version bumping. Fixes #205. --- update_version.sh | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100755 update_version.sh diff --git a/update_version.sh b/update_version.sh new file mode 100755 index 000000000..840c7b556 --- /dev/null +++ b/update_version.sh @@ -0,0 +1,28 @@ +#!/bin/sh + +if [ -z $1 ]; then + echo "USAGE: $0 " 1>&2 + exit 1 +fi + +NEWVERSION="$1" +echo "Updating version to '1.2.$NEWVERSION' ..." + +perl -w -pi -e 's/(VERSION 1\.2\.)\d+/${1}'$NEWVERSION'/;' CMakeLists.txt +perl -w -pi -e 's/(DYLIB_CURRENT_VERSION 12\.)\d+/${1}'$NEWVERSION'/;' CMakeLists.txt +perl -w -pi -e 's/(\-current_version,12\.)\d+/${1}'$NEWVERSION'/;' src/Makefile.darwin +perl -w -pi -e 's/(libSDL\-1\.2\.so\.1\.2\.)\d+/${1}'$NEWVERSION'/;' src/Makefile.linux +perl -w -pi -e 's/(VERSION = 1\.2\.)\d+/${1}'$NEWVERSION'/;' src/Makefile.os2 +perl -w -pi -e 's/(VERSION = 1\.2\.)\d+/${1}'$NEWVERSION'/;' src/Makefile.w32 +perl -w -pi -e 's/(\#define SDL12_COMPAT_VERSION )\d+/${1}'$NEWVERSION'/;' src/SDL12_compat.c +perl -w -pi -e 's/(\#define SDL_PATCHLEVEL )\d+/${1}'$NEWVERSION'/;' include/SDL/SDL_version.h +perl -w -pi -e 's/(FILEVERSION 1,2,)\d+/${1}'$NEWVERSION'/;' src/version.rc +perl -w -pi -e 's/(PRODUCTVERSION 1,2,)\d+/${1}'$NEWVERSION'/;' src/version.rc +perl -w -pi -e 's/(VALUE "FileVersion", "1, 2, )\d+/${1}'$NEWVERSION'/;' src/version.rc +perl -w -pi -e 's/(VALUE "ProductVersion", "1, 2, )\d+/${1}'$NEWVERSION'/;' src/version.rc + +echo "All done." +echo "Run 'git diff' and make sure this looks correct before 'git commit'." + +exit 0 + From d49b44d4a61b087253daea8591e4eedbd04bd195 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 16 Sep 2022 11:10:18 -0400 Subject: [PATCH 347/606] Bumped version to 1.2.56 for release! --- CMakeLists.txt | 4 ++-- include/SDL/SDL_version.h | 2 +- src/Makefile.darwin | 2 +- src/Makefile.linux | 2 +- src/Makefile.os2 | 2 +- src/Makefile.w32 | 2 +- src/SDL12_compat.c | 2 +- src/version.rc | 8 ++++---- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3c506c13c..e0332fefd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.0.0) project(sdl12_compat - VERSION 1.2.54 + VERSION 1.2.56 LANGUAGES C) option(SDL12TESTS "Enable to build SDL-1.2 test programs" ON) @@ -24,7 +24,7 @@ if(APPLE) # Xcode project file uses 1.0.0, but it's more compatible to use the # higher version. set(DYLIB_COMPAT_VERSION 12.0.0 CACHE STRING "library compatibility version") - set(DYLIB_CURRENT_VERSION 12.54.0 CACHE STRING "library current version") + set(DYLIB_CURRENT_VERSION 12.56.0 CACHE STRING "library current version") include_directories("/opt/X11/include") # hack. if(CMAKE_VERSION VERSION_LESS 3.9) else() diff --git a/include/SDL/SDL_version.h b/include/SDL/SDL_version.h index 00b4f64fd..a5efe8a5f 100644 --- a/include/SDL/SDL_version.h +++ b/include/SDL/SDL_version.h @@ -33,7 +33,7 @@ real SDL-1.2 available to you. */ /* We bumped the patchlevel to 50 for sdl12-compat */ #define SDL_MAJOR_VERSION 1 #define SDL_MINOR_VERSION 2 -#define SDL_PATCHLEVEL 54 +#define SDL_PATCHLEVEL 56 typedef struct SDL_version { diff --git a/src/Makefile.darwin b/src/Makefile.darwin index 07e3caa94..f2368508c 100644 --- a/src/Makefile.darwin +++ b/src/Makefile.darwin @@ -18,7 +18,7 @@ CFLAGS = -mmacosx-version-min=10.6 -fPIC -O3 -Wall LDFLAGS = -mmacosx-version-min=10.6 -dynamiclib -Wl,-undefined,error -Wl,-single_module #LDFLAGS+= -Wl,-headerpad_max_install_names LDFLAGS+= -Wl,-install_name,"/usr/local/lib/$(DYLIB)" -LDFLAGS+= -Wl,-compatibility_version,1.0 -Wl,-current_version,12.54 +LDFLAGS+= -Wl,-compatibility_version,1.0 -Wl,-current_version,12.56 LDLIBS = -Wl,-framework,AppKit # this is needed for x86_64 - cross-gcc might not add it. #LDLIBS += -Wl,-lbundle1.o diff --git a/src/Makefile.linux b/src/Makefile.linux index 2fecd5cdd..29f56dbda 100644 --- a/src/Makefile.linux +++ b/src/Makefile.linux @@ -16,7 +16,7 @@ LDFLAGS = -shared -Wl,-soname,libSDL-1.2.so.0 LDFLAGS+= -Wl,--no-undefined LDLIBS = -ldl -SHLIB = libSDL-1.2.so.1.2.54 +SHLIB = libSDL-1.2.so.1.2.56 OBJ = SDL12_compat.o diff --git a/src/Makefile.os2 b/src/Makefile.os2 index 4f8a2ea1b..ce4096ecb 100644 --- a/src/Makefile.os2 +++ b/src/Makefile.os2 @@ -5,7 +5,7 @@ !endif DLLNAME = SDL12 -VERSION = 1.2.54 +VERSION = 1.2.56 # change SDL2INC to point to the SDL2 headers SDL2INC = include diff --git a/src/Makefile.w32 b/src/Makefile.w32 index adf54a867..e9977ef99 100644 --- a/src/Makefile.w32 +++ b/src/Makefile.w32 @@ -5,7 +5,7 @@ !endif DLLNAME = SDL -VERSION = 1.2.54 +VERSION = 1.2.56 # change SDL2INC to point to the SDL2 headers SDL2INC = include diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index ba3112ef5..2dddc1693 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -28,7 +28,7 @@ * should be way ahead of what SDL-1.2 Classic would report, so apps can * decide if they're running under the compat layer, if they really care. */ -#define SDL12_COMPAT_VERSION 54 +#define SDL12_COMPAT_VERSION 56 #include #include diff --git a/src/version.rc b/src/version.rc index 81cc8db0a..678e85b19 100644 --- a/src/version.rc +++ b/src/version.rc @@ -3,8 +3,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,2,54,0 - PRODUCTVERSION 1,2,54,0 + FILEVERSION 1,2,56,0 + PRODUCTVERSION 1,2,56,0 FILEFLAGSMASK 0x3fL FILEFLAGS 0x0L FILEOS 0x40004L @@ -17,12 +17,12 @@ BEGIN BEGIN VALUE "CompanyName", "\0" VALUE "FileDescription", "SDL\0" - VALUE "FileVersion", "1, 2, 54, 0\0" + VALUE "FileVersion", "1, 2, 56, 0\0" VALUE "InternalName", "SDL\0" VALUE "LegalCopyright", "Copyright © 2022 Sam Lantinga\0" VALUE "OriginalFilename", "SDL.dll\0" VALUE "ProductName", "Simple DirectMedia Layer 1.2 wrapper\0" - VALUE "ProductVersion", "1, 2, 54, 0\0" + VALUE "ProductVersion", "1, 2, 56, 0\0" END END BLOCK "VarFileInfo" From f4e2d1a30a6df8fef72c283af466c6aa21ec1280 Mon Sep 17 00:00:00 2001 From: Joshua Root Date: Sat, 17 Sep 2022 11:08:07 +1000 Subject: [PATCH 348/606] Implement OS_GetExeName for macOS and FreeBSD --- src/SDL12_compat.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 2dddc1693..ddfd57943 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1223,6 +1223,15 @@ static void OS_GetExeName(char *buf, const unsigned maxpath) { buf[0] = '\0'; DosQueryModuleName(pib->pib_hmte, maxpath, buf); } +#elif defined(__APPLE__) || defined(__FREEBSD__) +static void OS_GetExeName(char *buf, const unsigned maxpath) { + const char *progname = getprogname(); + if (progname != NULL) { + strlcpy(buf, progname, maxpath); + } else { + buf[0] = '\0'; + } +} #else #warning Please implement this for your platform. static void OS_GetExeName(char *buf, const unsigned maxpath) { From 7411b4c5a8cdeede78b61b70489ebc658830db20 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sat, 17 Sep 2022 11:03:10 -0400 Subject: [PATCH 349/606] video: Wrap access to the SDL_Renderer in a mutex. Just in case this gets used from background threads. Reference Issue #176. (This probably doesn't _fix_ the issue there, but discussion happened in that issue.) --- src/SDL12_compat.c | 77 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 57 insertions(+), 20 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index ddfd57943..6ec6fb971 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -950,6 +950,7 @@ static SDL_bool VideoWindowGrabbed = SDL_FALSE; static SDL_bool VideoCursorHidden = SDL_FALSE; static SDL_Window *VideoWindow20 = NULL; static SDL_Renderer *VideoRenderer20 = NULL; +static SDL_mutex *VideoRendererLock = NULL; static SDL_Texture *VideoTexture20 = NULL; static SDL12_Surface *VideoSurface12 = NULL; static SDL_Palette *VideoPhysicalPalette20 = NULL; @@ -5245,6 +5246,10 @@ EndVidModeCreate(void) SDL20_DestroyRenderer(VideoRenderer20); VideoRenderer20 = NULL; } + if (VideoRendererLock) { + SDL20_DestroyMutex(VideoRendererLock); + VideoRendererLock = NULL; + } if (VideoGLContext20) { SDL20_GL_MakeCurrent(NULL, NULL); SDL20_GL_DeleteContext(VideoGLContext20); @@ -5601,12 +5606,25 @@ InitializeOpenGLScaling(const int w, const int h) after. Without this, we either need all apps to render exclusively on the main thread or fail to draw at all. - This feels risky, but it's better than the alternative! */ -static void ResetVideoRendererForThreading(void) + This feels risky, but it's better than the alternative! + + Also, the renderer API isn't thread safe in general, so wrapping it + in a mutex is necessary anyhow. */ + +static SDL_Renderer * +LockVideoRenderer(void) +{ + SDL20_LockMutex(VideoRendererLock); + return VideoRenderer20; +} + +static void +UnlockVideoRenderer(void) { if ((VideoRenderer20 != NULL) && (SDL20_GL_GetCurrentContext() != NULL)) { SDL20_GL_MakeCurrent(NULL, NULL); } + SDL20_UnlockMutex(VideoRendererLock); } static void HandleInputGrab(SDL12_GrabMode mode); @@ -5947,6 +5965,10 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12) const SDL_bool want_vsync = (vsync_env && SDL20_atoi(vsync_env)) ? SDL_TRUE : SDL_FALSE; SDL_RendererInfo rinfo; SDL_assert(!VideoGLContext20); /* either a new window or we destroyed all this */ + VideoRendererLock = SDL20_CreateMutex(); + if (!VideoRendererLock) { + return EndVidModeCreate(); + } if (!VideoRenderer20 && want_vsync) { VideoRenderer20 = SDL20_CreateRenderer(VideoWindow20, -1, SDL_RENDERER_ACCELERATED|SDL_RENDERER_PRESENTVSYNC); } @@ -6037,7 +6059,9 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12) VideoSurfaceLastPresentTicks = 0; if ((flags12 & SDL12_OPENGL) == 0) { - ResetVideoRendererForThreading(); + /* see notes above these functions about GL context resetting. Force a lock/unlock here to set that up. */ + LockVideoRenderer(); + UnlockVideoRenderer(); } return VideoSurface12; @@ -6326,13 +6350,14 @@ static void PresentScreen(void) { QueuedOverlayItem *overlay; + SDL_Renderer *renderer = LockVideoRenderer(); - if (!VideoRenderer20) { + if (!renderer) { return; } - SDL20_RenderClear(VideoRenderer20); - SDL20_RenderCopy(VideoRenderer20, VideoTexture20, NULL, NULL); + SDL20_RenderClear(renderer); + SDL20_RenderCopy(renderer, VideoTexture20, NULL, NULL); /* Render any pending YUV overlay over the surface texture. */ overlay = QueuedDisplayOverlays.next; @@ -6342,7 +6367,7 @@ PresentScreen(void) if (overlay->overlay12) { SDL12_YUVData *hwdata = (SDL12_YUVData *) overlay->overlay12->hwdata; SDL_Rect dstrect20; - SDL20_RenderCopy(VideoRenderer20, hwdata->texture20, NULL, Rect12to20(&overlay->dstrect12, &dstrect20)); + SDL20_RenderCopy(renderer, hwdata->texture20, NULL, Rect12to20(&overlay->dstrect12, &dstrect20)); } SDL_free(overlay); overlay = next; @@ -6351,11 +6376,11 @@ PresentScreen(void) QueuedDisplayOverlaysTail = &QueuedDisplayOverlays; } - SDL20_RenderPresent(VideoRenderer20); + SDL20_RenderPresent(renderer); VideoSurfaceLastPresentTicks = SDL20_GetTicks(); VideoSurfacePresentTicks = 0; - ResetVideoRendererForThreading(); + UnlockVideoRenderer(); } static void @@ -6789,9 +6814,12 @@ SDL_WM_ToggleFullScreen(SDL12_Surface *surface) VideoSurface12->flags |= SDL12_FULLSCREEN; } } - if (retval && VideoRenderer20) { - SDL20_RenderSetLogicalSize(VideoRenderer20, VideoSurface12->w, VideoSurface12->h); - ResetVideoRendererForThreading(); + if (retval) { + SDL_Renderer *renderer = LockVideoRenderer(); + if (renderer) { + SDL20_RenderSetLogicalSize(renderer, VideoSurface12->w, VideoSurface12->h); + UnlockVideoRenderer(); + } } } return retval; @@ -7087,6 +7115,7 @@ SDL_CreateYUVOverlay(int w, int h, Uint32 format12, SDL12_Surface *display12) const char *old_scale_quality = SDL20_GetHint(SDL_HINT_RENDER_SCALE_QUALITY); SDL12_Overlay *retval = NULL; SDL12_YUVData *hwdata = NULL; + SDL_Renderer *renderer = NULL; Uint32 format20 = 0; if (display12 != VideoSurface12) { /* SDL 1.2 doesn't check this, but it seems irresponsible not to. */ @@ -7099,8 +7128,6 @@ SDL_CreateYUVOverlay(int w, int h, Uint32 format12, SDL12_Surface *display12) return NULL; } - SDL_assert(VideoRenderer20 != NULL); - switch (format12) { #define SUPPORTED_YUV_FORMAT(x) case SDL12_##x##_OVERLAY: format20 = SDL_PIXELFORMAT_##x; break SUPPORTED_YUV_FORMAT(YV12); @@ -7138,9 +7165,14 @@ SDL_CreateYUVOverlay(int w, int h, Uint32 format12, SDL12_Surface *display12) hwdata->pitches[0] = w * 2; } + renderer = LockVideoRenderer(); + SDL20_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "0"); - hwdata->texture20 = SDL20_CreateTexture(VideoRenderer20, format20, SDL_TEXTUREACCESS_STREAMING, w, h); + hwdata->texture20 = SDL20_CreateTexture(renderer, format20, SDL_TEXTUREACCESS_STREAMING, w, h); SDL20_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, old_scale_quality); + + UnlockVideoRenderer(); + if (!hwdata->texture20) { SDL20_free(hwdata->pixelbuf); SDL20_free(retval); @@ -7159,8 +7191,6 @@ SDL_CreateYUVOverlay(int w, int h, Uint32 format12, SDL12_Surface *display12) retval->pixels = hwdata->pixels; hwdata->dirty = SDL_TRUE; - ResetVideoRendererForThreading(); - return retval; } @@ -7192,12 +7222,13 @@ SDL_DisplayYUVOverlay(SDL12_Overlay *overlay12, SDL12_Rect *dstrect12) { QueuedOverlayItem *overlay; SDL12_YUVData *hwdata; + SDL_Renderer *renderer = NULL; if (!overlay12) { return SDL20_InvalidParamError("overlay"); } else if (!dstrect12) { return SDL20_InvalidParamError("dstrect"); - } else if (!VideoRenderer20) { + } else if (!(renderer = LockVideoRenderer())) { return SDL20_SetError("No software screen surface available"); } @@ -7209,6 +7240,7 @@ SDL_DisplayYUVOverlay(SDL12_Overlay *overlay12, SDL12_Rect *dstrect12) } if ((overlay = (QueuedOverlayItem *) SDL_malloc(sizeof (QueuedOverlayItem))) == NULL) { + UnlockVideoRenderer(); return SDL20_OutOfMemory(); } @@ -7256,7 +7288,7 @@ SDL_DisplayYUVOverlay(SDL12_Overlay *overlay12, SDL12_Rect *dstrect12) VideoSurfacePresentTicks = VideoSurfaceLastPresentTicks + GetDesiredMillisecondsPerFrame(); /* flip it later. */ } - ResetVideoRendererForThreading(); + UnlockVideoRenderer(); return 0; } @@ -7273,6 +7305,7 @@ DECLSPEC12 void SDLCALL SDL_FreeYUVOverlay(SDL12_Overlay *overlay12) { if (overlay12) { + SDL_Renderer *renderer = LockVideoRenderer(); SDL12_YUVData *hwdata = (SDL12_YUVData *) overlay12->hwdata; QueuedOverlayItem *overlay = QueuedDisplayOverlays.next; while (overlay != NULL) { @@ -7281,7 +7314,11 @@ SDL_FreeYUVOverlay(SDL12_Overlay *overlay12) } } - SDL20_DestroyTexture(hwdata->texture20); + if (renderer) { + SDL20_DestroyTexture(hwdata->texture20); + UnlockVideoRenderer(); + } + SDL20_free(hwdata->pixelbuf); SDL20_free(overlay12); } From f152223ea16d93330452b9926faeb0a5ba6722e6 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sun, 18 Sep 2022 03:04:40 +0300 Subject: [PATCH 350/606] updated dr_libs from mainstream. --- src/dr_mp3.h | 40 +++++++++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/src/dr_mp3.h b/src/dr_mp3.h index 6fcc7e8c7..6e06ec1cd 100644 --- a/src/dr_mp3.h +++ b/src/dr_mp3.h @@ -1,6 +1,6 @@ /* MP3 audio decoder. Choice of public domain or MIT-0. See license statements at the end of this file. -dr_mp3 - v0.6.33 - 2022-04-10 +dr_mp3 - v0.6.34 - 2022-09-17 David Reid - mackron@gmail.com @@ -101,7 +101,7 @@ extern "C" { #define DRMP3_VERSION_MAJOR 0 #define DRMP3_VERSION_MINOR 6 -#define DRMP3_VERSION_REVISION 33 +#define DRMP3_VERSION_REVISION 34 #define DRMP3_VERSION_STRING DRMP3_XSTRINGIFY(DRMP3_VERSION_MAJOR) "." DRMP3_XSTRINGIFY(DRMP3_VERSION_MINOR) "." DRMP3_XSTRINGIFY(DRMP3_VERSION_REVISION) #include /* For size_t. */ @@ -353,7 +353,6 @@ typedef struct typedef struct { drmp3dec decoder; - drmp3dec_frame_info frameInfo; drmp3_uint32 channels; drmp3_uint32 sampleRate; drmp3_read_proc onRead; @@ -618,7 +617,7 @@ DRMP3_API const char* drmp3_version_string(void) #define DR_MP3_ONLY_SIMD #endif -#if ((defined(_MSC_VER) && _MSC_VER >= 1400) && (defined(_M_IX86) || defined(_M_X64))) || ((defined(__i386__) || defined(__x86_64__)) && defined(__SSE2__)) +#if ((defined(_MSC_VER) && _MSC_VER >= 1400) && defined(_M_X64)) || ((defined(__i386) || defined(_M_IX86) || defined(__i386__) || defined(__x86_64__)) && ((defined(_M_IX86_FP) && _M_IX86_FP == 2) || defined(__SSE2__))) #if defined(_MSC_VER) #include #endif @@ -1319,7 +1318,7 @@ static void drmp3_L3_huffman(float *dst, drmp3_bs *bs, const drmp3_L3_gr_info *g static const drmp3_int16 tabindex[2*16] = { 0,32,64,98,0,132,180,218,292,364,426,538,648,746,0,1126,1460,1460,1460,1460,1460,1460,1460,1460,1842,1842,1842,1842,1842,1842,1842,1842 }; static const drmp3_uint8 g_linbits[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,6,8,10,13,4,5,6,7,8,9,11,13 }; -#define DRMP3_PEEK_BITS(n) (bs_cache >> (32 - n)) +#define DRMP3_PEEK_BITS(n) (bs_cache >> (32 - (n))) #define DRMP3_FLUSH_BITS(n) { bs_cache <<= (n); bs_sh += (n); } #define DRMP3_CHECK_BITS while (bs_sh >= 0) { bs_cache |= (drmp3_uint32)*bs_next_ptr++ << bs_sh; bs_sh -= 8; } #define DRMP3_BSPOS ((bs_next_ptr - bs->buf)*8 - 24 + bs_sh) @@ -1887,7 +1886,7 @@ static void drmp3d_DCT_II(float *grbuf, int n) #if DRMP3_HAVE_SSE #define DRMP3_VSAVE2(i, v) _mm_storel_pi((__m64 *)(void*)&y[i*18], v) #else -#define DRMP3_VSAVE2(i, v) vst1_f32((float32_t *)&y[i*18], vget_low_f32(v)) +#define DRMP3_VSAVE2(i, v) vst1_f32((float32_t *)&y[(i)*18], vget_low_f32(v)) #endif for (i = 0; i < 7; i++, y += 4*18) { @@ -1903,7 +1902,7 @@ static void drmp3d_DCT_II(float *grbuf, int n) DRMP3_VSAVE2(3, t[3][7]); } else { -#define DRMP3_VSAVE4(i, v) DRMP3_VSTORE(&y[i*18], v) +#define DRMP3_VSAVE4(i, v) DRMP3_VSTORE(&y[(i)*18], v) for (i = 0; i < 7; i++, y += 4*18) { drmp3_f4 s = DRMP3_VADD(t[3][i], t[3][i + 1]); @@ -2453,7 +2452,7 @@ DRMP3_API void drmp3dec_f32_to_s16(const float *in, drmp3_int16 *out, size_t num /* The size in bytes of each chunk of data to read from the MP3 stream. minimp3 recommends at least 16K, but in an attempt to reduce data movement I'm making this slightly larger. */ #ifndef DRMP3_DATA_CHUNK_SIZE -#define DRMP3_DATA_CHUNK_SIZE DRMP3_MIN_DATA_CHUNK_SIZE*4 +#define DRMP3_DATA_CHUNK_SIZE (DRMP3_MIN_DATA_CHUNK_SIZE*4) #endif @@ -3442,10 +3441,23 @@ static drmp3_result drmp3_wfopen(FILE** ppFile, const wchar_t* pFilePath, const } #else /* - Use fopen() on anything other than Windows. Requires a conversion. This is annoying because fopen() is locale specific. The only real way I can - think of to do this is with wcsrtombs(). Note that wcstombs() is apparently not thread-safe because it uses a static global mbstate_t object for - maintaining state. I've checked this with -std=c89 and it works, but if somebody get's a compiler error I'll look into improving compatibility. + Use fopen() on anything other than Windows. Requires a conversion. This is annoying because + fopen() is locale specific. The only real way I can think of to do this is with wcsrtombs(). Note + that wcstombs() is apparently not thread-safe because it uses a static global mbstate_t object for + maintaining state. I've checked this with -std=c89 and it works, but if somebody get's a compiler + error I'll look into improving compatibility. */ + + /* + Some compilers don't support wchar_t or wcsrtombs() which we're using below. In this case we just + need to abort with an error. If you encounter a compiler lacking such support, add it to this list + and submit a bug report and it'll be added to the library upstream. + */ + #if defined(__DJGPP__) + { + /* Nothing to do here. This will fall through to the error check below. */ + } + #else { mbstate_t mbs; size_t lenMB; @@ -3487,6 +3499,7 @@ static drmp3_result drmp3_wfopen(FILE** ppFile, const wchar_t* pFilePath, const drmp3__free_from_callbacks(pFilePathMB, pAllocationCallbacks); } + #endif if (*ppFile == NULL) { return DRMP3_ERROR; @@ -4490,6 +4503,11 @@ counts rather than sample counts. /* REVISION HISTORY ================ +v0.6.34 - 2022-09-17 + - Fix compilation with DJGPP. + - Fix compilation when compiling with x86 with no SSE2. + - Remove an unnecessary variable from the drmp3 structure. + v0.6.33 - 2022-04-10 - Fix compilation error with the MSVC ARM64 build. - Fix compilation error on older versions of GCC. From 40dff443364acf998c6cc0d9d45f3a152aba9b05 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sun, 18 Sep 2022 18:01:02 -0400 Subject: [PATCH 351/606] video: Added SDL12COMPAT_MAX_VIDMODE hint to clamp max reported resolution. --- README.md | 12 ++++++++++++ src/SDL12_compat.c | 27 +++++++++++++++++++++------ 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index fc5e47516..201740d72 100644 --- a/README.md +++ b/README.md @@ -228,6 +228,18 @@ The available options are: will create the window at the originally-requested size. If this variable isn't specified, it defaults to 1.0 (no scaling). +- SDL12COMPAT_MAX_VIDMODE: (checked during SDL_Init) + This is a string in the form of `WxH`, where `W` is the maximum width + and `H` is the maximum height (for example: `640x480`). The list of valid + resolutions that will be reported by SDL_ListModes and SDL_VideoModeOK will + not include any dimensions that are wider or taller than these sizes. A size + of zero will be ignored, so for `0x480` a resolution of 1920x480 would be + accepted). If not specified, or set to `0x0`, no resolution clamping is done. + This is for old software-rendered games that might always choose the largest + resolution offered, but never conceived of 4K displays. In these cases, it + might be better for them to use a smaller resolution and let sdl12-compat + scale their output up with the GPU. + - SDL_MOUSE_RELATIVE_SCALING: (checked during SDL_SetVideoMode) If enabled, relative mouse motion is scaled when the application is running at a non-native resolution. This may be required with some diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 6ec6fb971..0787ac3d5 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1970,11 +1970,15 @@ VidModeSizeGreater(SDL12_Rect *mode1, SDL12_Rect *mode2) } static int -AddVidModeToList(VideoModeList *vmode, SDL12_Rect *mode) +AddVidModeToList(VideoModeList *vmode, SDL12_Rect *mode, const Uint16 maxw, const Uint16 maxh) { void *ptr = NULL; int i; + if ( (maxw && (mode->w > maxw)) || (maxh && (mode->h > maxh)) ) { + return 0; /* clamp this one out as too big. */ + } + /* make sure we don't have this one already (with a different refresh rate, etc). */ for (i = 0; i < vmode->nummodes; i++) { if ((vmode->modeslist12[i].w == mode->w) && (vmode->modeslist12[i].h == mode->h)) { @@ -2038,21 +2042,32 @@ static int Init12VidModes(void) { const int total = SDL20_GetNumDisplayModes(VideoDisplayIndex); + const char *maxmodestr; VideoModeList *vmode = NULL; void *ptr = NULL; int i, j; SDL12_Rect prev_mode = { 0, 0, 0, 0 }, current_mode = { 0, 0, 0, 0 }; /* We only want to enable fake modes if OpenGL Logical Scaling is enabled. */ const SDL_bool use_fake_modes = SDL12Compat_GetHintBoolean("SDL12COMPAT_OPENGL_SCALING", SDL_TRUE); - - WantOpenGLScaling = use_fake_modes; + Uint16 maxw = 0; + Uint16 maxh = 0; if (VideoModesCount > 0) { return 0; /* already did this. */ } + WantOpenGLScaling = use_fake_modes; + SDL_assert(VideoModes == NULL); + maxmodestr = SDL12Compat_GetHint("SDL12COMPAT_MAX_VIDMODE"); + if (maxmodestr) { + unsigned int w, h; + SDL_sscanf(maxmodestr, "%ux%u", &w, &h); + maxw = (Uint16) SDL_clamp(w, 0, 0xFFFF); + maxh = (Uint16) SDL_clamp(h, 0, 0xFFFF); + } + for (i = 0; i < total; ++i) { SDL_DisplayMode mode; @@ -2098,14 +2113,14 @@ Init12VidModes(void) if (use_fake_modes) { for (j = 0; j < (int) SDL_arraysize(fake_modes); ++j) { if (VidModeSizeGreater(&prev_mode, &fake_modes[j]) && VidModeSizeGreater(&fake_modes[j], ¤t_mode)) { - if (AddVidModeToList(vmode, &fake_modes[j])) { + if (AddVidModeToList(vmode, &fake_modes[j], maxw, maxh)) { return SDL20_OutOfMemory(); } } } } - if (AddVidModeToList(vmode, ¤t_mode)) { + if (AddVidModeToList(vmode, ¤t_mode, maxw, maxh)) { return SDL20_OutOfMemory(); } @@ -2117,7 +2132,7 @@ Init12VidModes(void) if (use_fake_modes) { for (i = 0; i < (int) SDL_arraysize(fake_modes); ++i) { if (VidModeSizeGreater(&prev_mode, &fake_modes[i])) { - if (AddVidModeToList(vmode, &fake_modes[i])) { + if (AddVidModeToList(vmode, &fake_modes[i], maxw, maxh)) { return SDL20_OutOfMemory(); } } From 8849617fe68828bf784567b770241be51f832642 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 19 Sep 2022 01:06:06 -0400 Subject: [PATCH 352/606] video: Try to move draws and PumpEvents out of background threads. This makes Civilization: Call to Power extremely playable. These changes are considered optional quirks; most things that do background rendering work at this point and these attempts to wrangle that tend to break them (tucnak, for example, _stops_ working in this new configuration). Reference Issue #176. --- src/SDL12_compat.c | 68 ++++++++++++++++++++++++++++++++++++++++++---- src/SDL20_syms.h | 2 +- 2 files changed, 63 insertions(+), 7 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 0787ac3d5..dc58df60d 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1023,6 +1023,11 @@ static EventQueueType EventQueuePool[SDL12_MAXEVENTS]; static EventQueueType *EventQueueHead = NULL; static EventQueueType *EventQueueTail = NULL; static EventQueueType *EventQueueAvailable = NULL; +static unsigned long SetVideoModeThread = 0; +static SDL_bool VideoSurfaceUpdatedInBackgroundThread = SDL_FALSE; +static SDL_bool AllowThreadedDraws = SDL_FALSE; +static SDL_bool AllowThreadedPumps = SDL_FALSE; + /* This is a KEYDOWN event which is being held for a follow-up TEXTINPUT */ static SDL12_Event PendingKeydownEvent; @@ -1197,6 +1202,14 @@ static QuirkEntryType quirks[] = { {"tucnak", "SDL_RENDER_DRIVER", "software"}, {"tucnak", "SDL_FRAMEBUFFER_ACCELERATION", "false"}, + /* Civilization: Call to Power draws and pumps from multiple threads at once, causing issues. */ + {"civctp", "SDL12COMPAT_ALLOW_THREADED_DRAWS", "0"}, + {"civctp", "SDL12COMPAT_ALLOW_THREADED_PUMPS", "0"}, + {"civctp.dynamic", "SDL12COMPAT_ALLOW_THREADED_DRAWS", "0"}, + {"civctp.dynamic", "SDL12COMPAT_ALLOW_THREADED_PUMPS", "0"}, + {"civctp.dynamic_fixed", "SDL12COMPAT_ALLOW_THREADED_DRAWS", "0"}, + {"civctp.dynamic_fixed", "SDL12COMPAT_ALLOW_THREADED_PUMPS", "0"}, + /* The 32-bit Steam build only of Multiwinia Quits but doesn't re-Init */ {"multiwinia.bin.x86", "SDL12COMPAT_NO_QUIT_VIDEO", "1"} #else @@ -2206,6 +2219,9 @@ Init12Video(void) SDL_DisplayMode mode; int i; + AllowThreadedDraws = SDL12Compat_GetHintBoolean("SDL12COMPAT_ALLOW_THREADED_DRAWS", SDL_TRUE); + AllowThreadedPumps = SDL12Compat_GetHintBoolean("SDL12COMPAT_ALLOW_THREADED_PUMPS", SDL_TRUE); + WantScaleMethodNearest = (scale_method_env && !SDL20_strcmp(scale_method_env, "nearest")) ? SDL_TRUE : SDL_FALSE; /* Only override this if the env var is set, as the default is platform-specific. */ @@ -2456,6 +2472,9 @@ Quit12Video(void) VideoModes = NULL; VideoModesCount = 0; + AllowThreadedDraws = SDL_FALSE; + AllowThreadedPumps = SDL_FALSE; + if (EventQueueMutex) { SDL20_DestroyMutex(EventQueueMutex); EventQueueMutex = NULL; @@ -5310,6 +5329,9 @@ EndVidModeCreate(void) QueuedDisplayOverlays.next = NULL; QueuedDisplayOverlaysTail = &QueuedDisplayOverlays; + VideoSurfaceUpdatedInBackgroundThread = SDL_FALSE; + SetVideoModeThread = 0; + return NULL; } @@ -6063,6 +6085,11 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12) } } + SetVideoModeThread = SDL20_ThreadID(); + VideoSurfacePresentTicks = 0; + VideoSurfaceLastPresentTicks = 0; + VideoSurfaceUpdatedInBackgroundThread = SDL_FALSE; + SDL20_RaiseWindow(VideoWindow20); /* SDL 1.2 always grabbed input if the video mode was fullscreen. */ @@ -6070,9 +6097,6 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12) HandleInputGrab(SDL12_GRAB_ON); } - VideoSurfacePresentTicks = 0; - VideoSurfaceLastPresentTicks = 0; - if ((flags12 & SDL12_OPENGL) == 0) { /* see notes above these functions about GL context resetting. Force a lock/unlock here to set that up. */ LockVideoRenderer(); @@ -6392,6 +6416,7 @@ PresentScreen(void) } SDL20_RenderPresent(renderer); + VideoSurfaceUpdatedInBackgroundThread = SDL_FALSE; VideoSurfaceLastPresentTicks = SDL20_GetTicks(); VideoSurfacePresentTicks = 0; @@ -6554,6 +6579,8 @@ SDL_GL_Unlock(void) DECLSPEC12 void SDLCALL SDL_UpdateRects(SDL12_Surface *surface12, int numrects, SDL12_Rect *rects12) { + const SDL_bool ThisIsSetVideoModeThread = (SDL20_ThreadID() == SetVideoModeThread); + /* strangely, SDL 1.2 doesn't check if surface12 is NULL before touching it */ /* (UpdateRect, singular, does...) */ @@ -6573,6 +6600,7 @@ SDL_UpdateRects(SDL12_Surface *surface12, int numrects, SDL12_Rect *rects12) * but in practice most apps never got a double-buffered surface and * don't handle it correctly, so we have to work around it. */ if (surface12 == VideoSurface12) { + const SDL_bool upload_later = !ThisIsSetVideoModeThread && !AllowThreadedDraws; SDL_Palette *logicalPal = surface12->surface20->format->palette; const int pixsize = surface12->format->BytesPerPixel; const int srcpitch = surface12->pitch; @@ -6584,7 +6612,10 @@ SDL_UpdateRects(SDL12_Surface *surface12, int numrects, SDL12_Rect *rects12) for (i = 0; i < numrects; i++) { UpdateRect12to20(surface12, &rects12[i], &rect20, &whole_screen); - if (!rect20.w || !rect20.h) { + + if (upload_later) { + continue; + } else if (!rect20.w || !rect20.h) { continue; } else if (SDL20_LockTexture(VideoTexture20, &rect20, &pixels, &pitch) < 0) { continue; /* oh well */ @@ -6623,7 +6654,10 @@ SDL_UpdateRects(SDL12_Surface *surface12, int numrects, SDL12_Rect *rects12) VideoConvertSurface20->h = VideoSurface12->h; } - if (whole_screen) { + if (upload_later) { + VideoSurfaceUpdatedInBackgroundThread = SDL_TRUE; + VideoSurfacePresentTicks = whole_screen ? 1 : VideoSurfaceLastPresentTicks + GetDesiredMillisecondsPerFrame(); /* flip it later (or as soon as the main thread can). */ + } else if (whole_screen) { PresentScreen(); /* flip it now. */ } else { VideoSurfacePresentTicks = VideoSurfaceLastPresentTicks + GetDesiredMillisecondsPerFrame(); /* flip it later. */ @@ -6676,14 +6710,24 @@ HandleKeyRepeat(void) DECLSPEC12 void SDLCALL SDL_PumpEvents(void) { + const SDL_bool ThisIsSetVideoModeThread = (SDL20_ThreadID() == SetVideoModeThread); SDL_Event e; + if (!ThisIsSetVideoModeThread && !AllowThreadedPumps) { + return; + } + /* If the app is doing dirty rectangles, we set a flag and present the * screen surface when they pump for new events if we're close to 60Hz, * which we consider a sign that they are done rendering for the current * frame and it would make sense to send it to the screen. */ + if (VideoSurfacePresentTicks && SDL_TICKS_PASSED(SDL20_GetTicks(), VideoSurfacePresentTicks)) { - PresentScreen(); + if (VideoSurfaceUpdatedInBackgroundThread) { + SDL_Flip(VideoSurface12); /* this will update the texture and present. */ + } else { + PresentScreen(); + } } if (EventQueueMutex) { @@ -7633,6 +7677,18 @@ SDL_SetTimer(Uint32 interval, SDL12_TimerCallback callback) return 0; } +DECLSPEC12 void SDLCALL +SDL_Delay(Uint32 ticks) +{ + /* In case there's a loading screen from a background thread and the main thread is waiting... */ + const SDL_bool ThisIsSetVideoModeThread = (SDL20_ThreadID() == SetVideoModeThread); + if (ThisIsSetVideoModeThread && VideoSurfaceUpdatedInBackgroundThread) { + SDL_Flip(VideoSurface12); /* this will update the texture and present. */ + } + SDL20_Delay(ticks); +} + + DECLSPEC12 int SDLCALL SDL_putenv(const char *_var) { diff --git a/src/SDL20_syms.h b/src/SDL20_syms.h index df76bfab9..e5469b8b5 100644 --- a/src/SDL20_syms.h +++ b/src/SDL20_syms.h @@ -232,7 +232,7 @@ SDL20_SYM_PASSTHROUGH(SDL_bool,HasAltiVec,(void),(),return) SDL20_SYM(SDL_TimerID,AddTimer,(Uint32 a, SDL_TimerCallback b, void *c),(a,b,c),return) SDL20_SYM(SDL_bool,RemoveTimer,(SDL_TimerID a),(a),return) SDL20_SYM_PASSTHROUGH(Uint32,GetTicks,(void),(),return) -SDL20_SYM_PASSTHROUGH(void,Delay,(Uint32 a),(a),) +SDL20_SYM(void,Delay,(Uint32 a),(a),) SDL20_SYM(SDL_bool,IsGameController,(int a),(a),return) SDL20_SYM(const char *,GameControllerNameForIndex,(int a),(a),return) From 918705031d7c0f4be905365f669636dd450eab47 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Mon, 19 Sep 2022 11:25:46 +0100 Subject: [PATCH 353/606] RestoreDestAlpha: Fix out-of-bounds access to buffer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since commit 812d58f, SaveDestAlpha only acts on a rectangle of size (dstrect12->w × dstrect12->h) at (dstrect12->x, dstrect12->y), but RestoreDestAlpha tries to act on a rectangle of size (dst12->w × dst12->h) at (dstrect12->x, dstrect12->y). For a non-trivial dstrect with x > 0 or y > 0, this resulted in invalid accesses outside the bounds of the pixel buffer and memory corruption. Fixes: 812d58f "video: Optimize temporarily saving of dest alpha for a blit" Resolves: https://github.com/libsdl-org/sdl12-compat/issues/211 Signed-off-by: Simon McVittie --- src/SDL12_compat.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index dc58df60d..854bfd1ee 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -6177,8 +6177,8 @@ RestoreDestAlpha(SDL12_Surface *dst12, Uint8 *dstalpha, const SDL12_Rect *dstrec if (dstalpha) { int x, y; - const int w = dst12->w; - const int h = dst12->h; + const int w = dstrect12->w; + const int h = dstrect12->h; const Uint8 *sptr = dstalpha; const Uint32 amask = dst12->format->Amask; const Uint32 ashift = dst12->format->Ashift; From e58a6589028b94c0e28b9466b090a8ea826f1fed Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 19 Sep 2022 09:03:23 -0400 Subject: [PATCH 354/606] video: SDL_SetVideoMode(x,x,0,x) now gets ONLY 16 or 32-bit formats. SDL 1.2 returns a 32-bit surface with a zero alpha mask for `SDL_SetVideoMode(w, h, 0, 0)` on this laptop, fwiw, so returning 24 was probably always wrong here. Also there's a million other ways this can go wrong, so just make sure it's either 16 or 32 bits. This makes Tucnak work again after we changed the 24-bit format, since its 24-bit rendering code in libzia has a bug, and was probably never actually used before. Fixes #213. --- src/SDL12_compat.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 854bfd1ee..b8f538247 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -5743,6 +5743,11 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12) if (bpp == 0) { flags12 |= SDL12_ANYFORMAT; bpp = SDL_BITSPERPIXEL(dmode.format); + /* keep this simple: we aren't handling palettes here, so for < 16-bit + formats, give them 16-bit and we'll convert later. Nothing in SDL 1.2 will + handle > 32 bits, so clamp there, too. AND ALSO, most apps will handle 32-bits + but not 24, so force around that...so basically, you can have 16 or 32 bit. */ + bpp = (bpp <= 16) ? 16 : 32; } if ((bpp != 8) && (bpp != 16) && (bpp != 24) && (bpp != 32)) { From 9da8808c03e80a228ee66a714091249f331ebcd7 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 23 Sep 2022 12:35:40 -0400 Subject: [PATCH 355/606] video: Don't ever simulate a hardware palette. Most scenarios wouldn't have offered it in classic SDL 1.2 anyhow, and some games misbehave with it. Fixes #216. --- src/SDL12_compat.c | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index b8f538247..18130aa12 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -953,7 +953,6 @@ static SDL_Renderer *VideoRenderer20 = NULL; static SDL_mutex *VideoRendererLock = NULL; static SDL_Texture *VideoTexture20 = NULL; static SDL12_Surface *VideoSurface12 = NULL; -static SDL_Palette *VideoPhysicalPalette20 = NULL; static Uint32 VideoSurfacePresentTicks = 0; static Uint32 VideoSurfaceLastPresentTicks = 0; static SDL_Surface *VideoConvertSurface20 = NULL; @@ -5293,10 +5292,6 @@ EndVidModeCreate(void) SDL20_DestroyWindow(VideoWindow20); VideoWindow20 = NULL; } - if (VideoPhysicalPalette20) { - SDL20_FreePalette(VideoPhysicalPalette20); - VideoPhysicalPalette20 = NULL; - } if (VideoSurface12) { SDL20_free(VideoSurface12->pixels); VideoSurface12->pixels = NULL; @@ -6080,13 +6075,6 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12) { const int x = (i & 0x3) | ((i & 0x3) << 2); color->b = x | x << 4; } color->a = 255; } - if (!VideoPhysicalPalette20) { - VideoPhysicalPalette20 = SDL20_AllocPalette(256); - if (!VideoPhysicalPalette20) { - return EndVidModeCreate(); - } - } - SDL20_SetPaletteColors(VideoPhysicalPalette20, VideoSurface12->format->palette->colors, 0, 256); } } @@ -6606,7 +6594,6 @@ SDL_UpdateRects(SDL12_Surface *surface12, int numrects, SDL12_Rect *rects12) * don't handle it correctly, so we have to work around it. */ if (surface12 == VideoSurface12) { const SDL_bool upload_later = !ThisIsSetVideoModeThread && !AllowThreadedDraws; - SDL_Palette *logicalPal = surface12->surface20->format->palette; const int pixsize = surface12->format->BytesPerPixel; const int srcpitch = surface12->pitch; SDL_bool whole_screen = SDL_FALSE; @@ -6631,7 +6618,6 @@ SDL_UpdateRects(SDL12_Surface *surface12, int numrects, SDL12_Rect *rects12) dstrect20.x = dstrect20.y = 0; dstrect20.w = rect20.w; dstrect20.h = rect20.h; - surface12->surface20->format->palette = VideoPhysicalPalette20; VideoConvertSurface20->pixels = pixels; VideoConvertSurface20->pitch = pitch; VideoConvertSurface20->w = rect20.w; @@ -6652,7 +6638,6 @@ SDL_UpdateRects(SDL12_Surface *surface12, int numrects, SDL12_Rect *rects12) } if (VideoConvertSurface20) { /* reset some state we messed with */ - surface12->surface20->format->palette = logicalPal; VideoConvertSurface20->pixels = NULL; VideoConvertSurface20->pitch = 0; VideoConvertSurface20->w = VideoSurface12->w; @@ -7046,21 +7031,11 @@ SDL_SetPalette(SDL12_Surface *surface12, int flags, const SDL_Color *colors, } } - if ((flags & SDL12_PHYSPAL) && (surface12 == VideoSurface12) && VideoPhysicalPalette20) { - if (SDL20_SetPaletteColors(VideoPhysicalPalette20, opaquecolors, firstcolor, ncolors) < 0) { - retval = -1; - } - } - SDL20_free(opaquecolors); /* in case this pointer changed... */ palette12->colors = palette20->colors; - if ((surface12 == VideoSurface12) && (flags & SDL12_PHYSPAL)) { - SDL_UpdateRect(surface12, 0, 0, 0, 0); /* force screen to reblit with new palette. */ - } - return retval; } From bf91f6aad1fce952a3c11dc6ace155a2d1f428b8 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Fri, 23 Sep 2022 22:21:10 +0300 Subject: [PATCH 356/606] mac: search for libSDL2-2.0.dylib along with libSDL2-2.0.0.dylib autotools builds output libSDL2-2.0.0.dylib, but cmake in all of its wisdom, outputs libSDL2-2.0.dylib... Reference issue: https://github.com/libsdl-org/sdl12-compat/issues/217 --- src/SDL12_compat.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 18130aa12..d1b69fa8c 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1082,6 +1082,8 @@ static char loaderror[256]; #include #include #define SDL20_LIBNAME "libSDL2-2.0.0.dylib" + /* SDL2 cmake'ry is (was?) messy: */ + #define SDL20_LIBNAME2 "libSDL2-2.0.dylib" #define SDL20_FRAMEWORK "SDL2.framework/Versions/A/SDL2" #define SDL20_REQUIRED_VER SDL_VERSIONNUM(2,0,7) #define strcpy_fn strcpy @@ -1093,12 +1095,15 @@ static char loaderror[256]; /* I don't know if this is the _right_ order to try, but this seems reasonable */ static const char * const dylib_locations[] = { "@loader_path/" SDL20_LIBNAME, /* MyApp.app/Contents/MacOS/libSDL2-2.0.0.dylib */ + "@loader_path/" SDL20_LIBNAME2, /* MyApp.app/Contents/MacOS/libSDL2-2.0.dylib */ "@loader_path/../Frameworks/" SDL20_FRAMEWORK, /* MyApp.app/Contents/Frameworks/SDL2.framework */ "@executable_path/" SDL20_LIBNAME, /* MyApp.app/Contents/MacOS/libSDL2-2.0.0.dylib */ + "@executable_path/" SDL20_LIBNAME2, /* MyApp.app/Contents/MacOS/libSDL2-2.0.dylib */ "@executable_path/../Frameworks/" SDL20_FRAMEWORK, /* MyApp.app/Contents/Frameworks/SDL2.framework */ NULL, /* /Users/username/Library/Frameworks/SDL2.framework */ "/Library/Frameworks" SDL20_FRAMEWORK, /* /Library/Frameworks/SDL2.framework */ - SDL20_LIBNAME /* oh well, anywhere the system can see the .dylib (/usr/local/lib or whatever) */ + SDL20_LIBNAME, /* oh well, anywhere the system can see the .dylib (/usr/local/lib or whatever) */ + SDL20_LIBNAME2 }; int i; From d1ca21fbcc6eb3d4cc141cd3e48a8ceebb873e8e Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Fri, 23 Sep 2022 23:00:04 +0300 Subject: [PATCH 357/606] test/checkkeys.c: fix watcom builds --- test/checkkeys.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/test/checkkeys.c b/test/checkkeys.c index 2df1d90ed..86ead56dd 100644 --- a/test/checkkeys.c +++ b/test/checkkeys.c @@ -76,9 +76,12 @@ static void PrintKey(SDL_keysym *sym, int pressed) else printf(" (0x%.4X)", (int)sym->unicode); #else /* other platforms than Windows hopefully use UTF-8 for 8bit chars */ - Uint32 utf32str[2] = { sym->unicode, 0 }; const char* utf32type = (SDL_BYTEORDER == SDL_LIL_ENDIAN) ? "UTF-32LE" : "UTF-32BE"; - char* utf8str = SDL_iconv_string("UTF-8", utf32type, (const char*)utf32str, 2*4); + char* utf8str; + Uint32 utf32str[2]; + utf32str[0] = sym->unicode; + utf32str[1] = 0; + utf8str = SDL_iconv_string("UTF-8", utf32type, (const char*)utf32str, 2*4); printf(" '%s' (0x%.4X)", utf8str, (int)sym->unicode); SDL_free(utf8str); #endif From c105fe7c79a5f39d9f7b1b08bcdb08429caa3a47 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Fri, 23 Sep 2022 23:00:04 +0300 Subject: [PATCH 358/606] test/checkkeys.c: leave os/2 alone as it had been before --- test/checkkeys.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/checkkeys.c b/test/checkkeys.c index 86ead56dd..38ab43cdb 100644 --- a/test/checkkeys.c +++ b/test/checkkeys.c @@ -69,7 +69,7 @@ static void PrintKey(SDL_keysym *sym, int pressed) } else { #ifdef UNICODE printf(" '%c' (0x%.4X)", sym->unicode, (int)sym->unicode); -#elif defined(_WIN32) +#elif defined(_WIN32) || defined(__OS2__) /* This is a Latin-1 program, so only show 8-bits */ if ( !(sym->unicode & 0xFF00) ) printf(" '%c' (0x%.4X)", sym->unicode, (int)sym->unicode); From 7be4b3c99a436e360a43aefc929087c46cdadee9 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Fri, 23 Sep 2022 23:00:04 +0300 Subject: [PATCH 359/606] silenced warnings from SDL12COMPAT_MAX_VIDMODE parsing. --- src/SDL12_compat.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index d1b69fa8c..4104fa972 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -2079,10 +2079,10 @@ Init12VidModes(void) maxmodestr = SDL12Compat_GetHint("SDL12COMPAT_MAX_VIDMODE"); if (maxmodestr) { - unsigned int w, h; + unsigned int w = 0, h = 0; SDL_sscanf(maxmodestr, "%ux%u", &w, &h); - maxw = (Uint16) SDL_clamp(w, 0, 0xFFFF); - maxh = (Uint16) SDL_clamp(h, 0, 0xFFFF); + if (w > 0xFFFF) w = 0xFFFF; + if (h > 0xFFFF) h = 0xFFFF; } for (i = 0; i < total; ++i) { From 8f9d2cc91afa19f45391efd8ca0cbb6070210e15 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Fri, 23 Sep 2022 23:28:02 +0300 Subject: [PATCH 360/606] restore buildability using c++ compilers --- src/SDL12_compat.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 4104fa972..abdbc7a4b 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -6577,7 +6577,7 @@ SDL_GL_Unlock(void) DECLSPEC12 void SDLCALL SDL_UpdateRects(SDL12_Surface *surface12, int numrects, SDL12_Rect *rects12) { - const SDL_bool ThisIsSetVideoModeThread = (SDL20_ThreadID() == SetVideoModeThread); + const SDL_bool ThisIsSetVideoModeThread = (SDL20_ThreadID() == SetVideoModeThread) ? SDL_TRUE : SDL_FALSE; /* strangely, SDL 1.2 doesn't check if surface12 is NULL before touching it */ /* (UpdateRect, singular, does...) */ @@ -6598,7 +6598,7 @@ SDL_UpdateRects(SDL12_Surface *surface12, int numrects, SDL12_Rect *rects12) * but in practice most apps never got a double-buffered surface and * don't handle it correctly, so we have to work around it. */ if (surface12 == VideoSurface12) { - const SDL_bool upload_later = !ThisIsSetVideoModeThread && !AllowThreadedDraws; + const SDL_bool upload_later = (!ThisIsSetVideoModeThread && !AllowThreadedDraws) ? SDL_TRUE : SDL_FALSE; const int pixsize = surface12->format->BytesPerPixel; const int srcpitch = surface12->pitch; SDL_bool whole_screen = SDL_FALSE; @@ -6705,7 +6705,7 @@ HandleKeyRepeat(void) DECLSPEC12 void SDLCALL SDL_PumpEvents(void) { - const SDL_bool ThisIsSetVideoModeThread = (SDL20_ThreadID() == SetVideoModeThread); + const SDL_bool ThisIsSetVideoModeThread = (SDL20_ThreadID() == SetVideoModeThread) ? SDL_TRUE : SDL_FALSE; SDL_Event e; if (!ThisIsSetVideoModeThread && !AllowThreadedPumps) { @@ -7666,7 +7666,7 @@ DECLSPEC12 void SDLCALL SDL_Delay(Uint32 ticks) { /* In case there's a loading screen from a background thread and the main thread is waiting... */ - const SDL_bool ThisIsSetVideoModeThread = (SDL20_ThreadID() == SetVideoModeThread); + const SDL_bool ThisIsSetVideoModeThread = (SDL20_ThreadID() == SetVideoModeThread) ? SDL_TRUE : SDL_FALSE; if (ThisIsSetVideoModeThread && VideoSurfaceUpdatedInBackgroundThread) { SDL_Flip(VideoSurface12); /* this will update the texture and present. */ } From 59dd259b5b5dd0a9fda7e40b2b5354946c549623 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Fri, 23 Sep 2022 23:28:02 +0300 Subject: [PATCH 361/606] minor whitespace tidy-up --- src/SDL12_compat.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index abdbc7a4b..76b6f9873 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -25,8 +25,8 @@ /* * We report the library version as 1.2.$(SDL12_COMPAT_VERSION). This number - * should be way ahead of what SDL-1.2 Classic would report, so apps can - * decide if they're running under the compat layer, if they really care. + * should be way ahead of what SDL-1.2 Classic would report, so apps can + * decide if they're running under the compat layer, if they really care. */ #define SDL12_COMPAT_VERSION 56 @@ -6116,8 +6116,8 @@ SaveDestAlpha(SDL12_Surface *src12, SDL12_Surface *dst12, const SDL12_Rect *dstr /* The 1.2 docs say this: * RGBA->RGBA: * SDL_SRCALPHA set: - * alpha-blend (using the source alpha channel) the RGB values; - * leave destination alpha untouched. [Note: is this correct?] + * alpha-blend (using the source alpha channel) the RGB values; + * leave destination alpha untouched. [Note: is this correct?] * * In SDL2, we change the destination alpha. We have to save it off in this case, which sucks. */ @@ -6595,8 +6595,8 @@ SDL_UpdateRects(SDL12_Surface *surface12, int numrects, SDL12_Rect *rects12) } /* everything else is marked SDL12_DOUBLEBUF and SHOULD BE a no-op here, - * but in practice most apps never got a double-buffered surface and - * don't handle it correctly, so we have to work around it. */ + * but in practice most apps never got a double-buffered surface and + * don't handle it correctly, so we have to work around it. */ if (surface12 == VideoSurface12) { const SDL_bool upload_later = (!ThisIsSetVideoModeThread && !AllowThreadedDraws) ? SDL_TRUE : SDL_FALSE; const int pixsize = surface12->format->BytesPerPixel; @@ -6713,9 +6713,9 @@ SDL_PumpEvents(void) } /* If the app is doing dirty rectangles, we set a flag and present the - * screen surface when they pump for new events if we're close to 60Hz, - * which we consider a sign that they are done rendering for the current - * frame and it would make sense to send it to the screen. */ + * screen surface when they pump for new events if we're close to 60Hz, + * which we consider a sign that they are done rendering for the current + * frame and it would make sense to send it to the screen. */ if (VideoSurfacePresentTicks && SDL_TICKS_PASSED(SDL20_GetTicks(), VideoSurfacePresentTicks)) { if (VideoSurfaceUpdatedInBackgroundThread) { @@ -6742,7 +6742,6 @@ SDL_PumpEvents(void) if (EventQueueMutex) { SDL20_UnlockMutex(EventQueueMutex); } - } DECLSPEC12 void SDLCALL @@ -6889,7 +6888,7 @@ UpdateRelativeMouseMode(void) MouseInputIsRelative = enable; if (MouseInputIsRelative) { /* reset position, we'll have to track it ourselves in SDL_MOUSEMOTION events, since 1.2 - * would give you window coordinates, even in relative mode. */ + * would give you window coordinates, even in relative mode. */ SDL20_GetMouseState(&MousePosition.x, &MousePosition.y); AdjustOpenGLLogicalScalingPoint(&MousePosition.x, &MousePosition.y); } @@ -7020,7 +7019,7 @@ SDL_SetPalette(SDL12_Surface *surface12, int flags, const SDL_Color *colors, } /* don't SDL_memcpy in case the 'a' field is uninitialized and upsets - * memory tools like Valgrind. */ + * memory tools like Valgrind. */ for (i = 0; i < ncolors; i++) { opaquecolors[i].r = colors[i].r; opaquecolors[i].g = colors[i].g; From f6923c5eeaa90cfc5aeccaa92ac35760c9360883 Mon Sep 17 00:00:00 2001 From: Cameron Cawley Date: Sat, 24 Sep 2022 13:43:25 +0100 Subject: [PATCH 362/606] Build SDLmain.lib for Windows with OpenWatcom --- src/Makefile.w32 | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/src/Makefile.w32 b/src/Makefile.w32 index e9977ef99..2f05d52c6 100644 --- a/src/Makefile.w32 +++ b/src/Makefile.w32 @@ -9,7 +9,7 @@ VERSION = 1.2.56 # change SDL2INC to point to the SDL2 headers SDL2INC = include -INCPATH = -I"$(%WATCOM)/h/nt" -I"$(%WATCOM)/h" -I"$(SDL2INC)" +INCPATH = -I"$(%WATCOM)/h/nt" -I"$(%WATCOM)/h" LIBNAME = $(DLLNAME) DLLFILE = $(LIBNAME).dll @@ -25,13 +25,21 @@ CFLAGS+= -wcd=200 CFLAGS+= -wcd=303 # the include paths : CFLAGS+= $(INCPATH) +# misc +CFLAGS+= -DNDEBUG -DSDL_DISABLE_IMMINTRIN_H + +CFLAGS_DLL = $(CFLAGS) # building dll: -CFLAGS+= -bd +CFLAGS_DLL+= -bd +# the include paths : +CFLAGS_DLL+= -I"$(SDL2INC)" # we override the DECLSPEC define in begin_code.h, because we are using # an exports file to remove the _cdecl '_' prefix from the symbol names -CFLAGS+= -DDECLSPEC= -# misc -CFLAGS+= -DNDEBUG -DSDL_DISABLE_IMMINTRIN_H +CFLAGS_DLL+= -DDECLSPEC= + +CFLAGS_SDLMAIN = $(CFLAGS) +# the include paths : +CFLAGS_SDLMAIN+= -I"../include/SDL" object_files= SDL12_compat.obj resource_obj= version.res @@ -40,11 +48,11 @@ resource_obj= version.res .extensions: .lib .dll .obj .c .asm .res .rc .c.obj: - wcc386 $(CFLAGS) -fo=$^@ $< + wcc386 $(CFLAGS_DLL) -fo=$^@ $< .rc.res: wrc -q -r -bt=nt -I"$(%WATCOM)/h/nt" -fo=$^@ $< -all: $(DLLFILE) $(LIBFILE) .symbolic +all: $(DLLFILE) $(LIBFILE) SDLmain.lib .symbolic $(DLLFILE): compiling_info $(object_files) $(resource_obj) $(LNKFILE) @echo * Linking: $@ @@ -54,6 +62,12 @@ $(LIBFILE): $(DLLFILE) @echo * Creating LIB file: $@ wlib -q -b -n -c -pa -s -t -zld -ii -io $* @SDL12.lbc +SDLmain.lib: SDL_win32_main.obj + wlib -q -b -n $@ -+SDL_win32_main.obj + +SDL_win32_main.obj : SDLmain/win32/SDL_win32_main.c + wcc386 $(CFLAGS_SDLMAIN) -fo=$^@ $< + compiling_info : .symbolic @echo * Compiling... @@ -83,3 +97,4 @@ distclean: clean .SYMBOLIC @if exist *.err rm *.err @if exist $(DLLFILE) rm $(DLLFILE) @if exist $(LIBFILE) rm $(LIBFILE) + @if exist SDLmain.lib rm SDLmain.lib From 270afba867be52d2d0074fbf3f14dc1bbe872dfe Mon Sep 17 00:00:00 2001 From: Cameron Cawley Date: Sat, 24 Sep 2022 13:44:11 +0100 Subject: [PATCH 363/606] Add makefiles for building the tests with OpenWatcom --- test/Makefile.os2 | 34 ++++++++++++++++++++++++++++++++++ test/Makefile.w32 | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 test/Makefile.os2 create mode 100644 test/Makefile.w32 diff --git a/test/Makefile.os2 b/test/Makefile.os2 new file mode 100644 index 000000000..5f45c2580 --- /dev/null +++ b/test/Makefile.os2 @@ -0,0 +1,34 @@ +TARGETS = checkkeys.exe graywin.exe loopwave.exe testalpha.exe testbitmap.exe & + testblitspeed.exe testcdrom.exe testcursor.exe testdyngl.exe & + testerror.exe testfile.exe testgamma.exe testgl.exe testthread.exe & + testiconv.exe testjoystick.exe testkeys.exe testlock.exe & + testoverlay2.exe testoverlay.exe testpalette.exe testplatform.exe & + testsem.exe testsprite.exe testtimer.exe testver.exe testvidinfo.exe & + testwin.exe testwm.exe threadwin.exe torturethread.exe testloadso.exe + +OBJS = $(TARGETS:.exe=.obj) + +all: $(TARGETS) + +BINPATH = . +INCPATH = -I"$(%WATCOM)/h/os2" -I"$(%WATCOM)/h" -I"../include/SDL" +CFLAGS_DEF = $(INCPATH) -bt=os2 -d0 -q -bm -5s -fp5 -fpi87 -sg -oteanbmier +CFLAGS_EXE = $(CFLAGS_DEF) +CFLAGS = $(CFLAGS_EXE) -ei -5s + +LIBPATH = ../src +LIBS = SDL12.lib + +.obj.exe: + wlink SYS os2v2 libpath $(LIBPATH) lib {$(LIBS)} op q file {$<} name $* + +.c.obj: + wcc386 $(CFLAGS) -fo=$^@ $< + +clean: .SYMBOLIC + @echo * Clean tests in $(BINPATH) + @if exist *.obj rm *.obj + @if exist *.err rm *.err + +distclean: clean .SYMBOLIC + @if exist *.exe rm *.exe diff --git a/test/Makefile.w32 b/test/Makefile.w32 new file mode 100644 index 000000000..793031c27 --- /dev/null +++ b/test/Makefile.w32 @@ -0,0 +1,35 @@ +TARGETS = checkkeys.exe graywin.exe loopwave.exe testalpha.exe testbitmap.exe & + testblitspeed.exe testcdrom.exe testcursor.exe testdyngl.exe & + testerror.exe testfile.exe testgamma.exe testgl.exe testthread.exe & + testiconv.exe testjoystick.exe testkeys.exe testlock.exe & + testoverlay2.exe testoverlay.exe testpalette.exe testplatform.exe & + testsem.exe testsprite.exe testtimer.exe testver.exe testvidinfo.exe & + testwin.exe testwm.exe threadwin.exe torturethread.exe testloadso.exe + +OBJS = $(TARGETS:.exe=.obj) + +all: $(TARGETS) + +BINPATH = . +INCPATH = -I"$(%WATCOM)/h/nt" -I"$(%WATCOM)/h" -I"../include/SDL" +CFLAGS_DEF = $(INCPATH) -bt=nt -d0 -q -bm -5s -fp5 -fpi87 -sg -oteanbmier +CFLAGS_EXE = $(CFLAGS_DEF) +CFLAGS = $(CFLAGS_EXE) -ei -5s + +LIBPATH = ../src +LIBS = SDL.lib +LIBF = SDLmain.lib + +.obj.exe: + wlink SYS nt libpath $(LIBPATH) libf {$(LIBF)} lib {$(LIBS)} op q file {$<} name $* + +.c.obj: + wcc386 $(CFLAGS) -fo=$^@ $< + +clean: .SYMBOLIC + @echo * Clean tests in $(BINPATH) + @if exist *.obj rm *.obj + @if exist *.err rm *.err + +distclean: clean .SYMBOLIC + @if exist *.exe rm *.exe From c17de0e7c800bd30979c2beccb35663e95f14e7b Mon Sep 17 00:00:00 2001 From: Cameron Cawley Date: Sat, 24 Sep 2022 13:45:02 +0100 Subject: [PATCH 364/606] Add OpenWatcom builds to GitHub Actions --- .github/workflows/watcom.yml | 39 ++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 .github/workflows/watcom.yml diff --git a/.github/workflows/watcom.yml b/.github/workflows/watcom.yml new file mode 100644 index 000000000..960487d82 --- /dev/null +++ b/.github/workflows/watcom.yml @@ -0,0 +1,39 @@ +name: Build (OpenWatcom) + +on: [push, pull_request] + +jobs: + os2: + name: ${{ matrix.platform.name }} + runs-on: windows-latest + + strategy: + matrix: + platform: + - { name: Windows, makefile: Makefile.w32 } + - { name: OS/2, makefile: Makefile.os2 } + + steps: + - uses: open-watcom/setup-watcom@v0 + - name: Get sdl12-compat sources + uses: actions/checkout@v2 + - name: Get SDL2 headers + uses: actions/checkout@v2 + with: + repository: libsdl-org/SDL + ref: release-2.24.0 + path: SDL2 + - name: Build sdl12-compat + run: | + cd src && wmake -f ${{ matrix.platform.makefile }} SDL2INC="${{ github.workspace }}/SDL2/include" + cd .. + - name: Build tests + run: | + cd test && wmake -f ${{ matrix.platform.makefile }} + cd .. + - name: distclean + run: | + cd src && wmake -f ${{ matrix.platform.makefile }} distclean + cd .. + cd test && wmake -f ${{ matrix.platform.makefile }} distclean + cd .. From 712c5221b019e48ec15a1d0845551d842fe7cf0a Mon Sep 17 00:00:00 2001 From: Cameron Cawley Date: Sat, 24 Sep 2022 15:53:29 +0100 Subject: [PATCH 365/606] testiconv: Print the total number of errors at the end --- test/testiconv.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/testiconv.c b/test/testiconv.c index 7e71320c1..5b2ae8d91 100644 --- a/test/testiconv.c +++ b/test/testiconv.c @@ -69,5 +69,7 @@ int main(int argc, char *argv[]) fputs(test[0], stdout); SDL_free(test[0]); } + + fprintf(stderr, "\nTotal errors: %d\n", errors); return (errors ? errors + 1 : 0); } From cc23a07dc4c7a720d192285cc38d1bd90508f72d Mon Sep 17 00:00:00 2001 From: David Gow Date: Sun, 25 Sep 2022 18:05:34 +0800 Subject: [PATCH 366/606] Clamp mouse coordinates to the backbuffer size for non-OpenGL When we're logically scaling, and preserving the aspect ratio (so are letterboxing or pillarboxing), the scaled mouse coordinates may be outside the application window (backbuffer). These can even be negative, which get underflowed to very large positive values, as SDL 1.2 uses unsigned coordinates here. We were already clamping these values for OpenGL logical scaling, which we do ourselves, but the event filter used with SDL_Renderer doesn't, so we'll manually clamp these all the time. --- src/SDL12_compat.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 76b6f9873..5ee543bd5 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -4512,6 +4512,9 @@ EventFilter20to12(void *data, SDL_Event *event20) event12.motion.which = (Uint8) event20->motion.which; event12.motion.state = event20->motion.state; AdjustOpenGLLogicalScalingPoint(&event20->motion.x, &event20->motion.y); + /* Clamp the absolute position to the window dimensions. */ + event20->motion.x = SDL_max(SDL_min(event20->motion.x, VideoSurface12->w), 0); + event20->motion.y = SDL_max(SDL_min(event20->motion.y, VideoSurface12->h), 0); event12.motion.x = (Uint16) event20->motion.x; event12.motion.y = (Uint16) event20->motion.y; if (UseMouseRelativeScaling) { From 6ed2edf39004cafff0043b1f7f4b50cd2fc2904c Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Tue, 27 Sep 2022 03:32:26 +0200 Subject: [PATCH 367/606] cmake: move includes to top of CMakeLists.txt --- CMakeLists.txt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e0332fefd..b3400d78a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,6 +15,11 @@ if(STATICDEVEL AND NOT (CMAKE_SYSTEM_NAME MATCHES "Linux")) MESSAGE(FATAL_ERROR "Static builds are only supported on Linux.") endif() +include(CheckCSourceCompiles) +include(CheckIncludeFile) +include(CheckCCompilerFlag) +include(GNUInstallDirs) + set(CMAKE_SKIP_RPATH TRUE) if(APPLE) @@ -43,11 +48,6 @@ set(SDL12COMPAT_SRCS ) add_library(SDL SHARED ${SDL12COMPAT_SRCS}) -include(CheckCSourceCompiles) -include(CheckIncludeFile) -include(CheckCCompilerFlag) - -include(GNUInstallDirs) include("cmake/modules/FindSDL2.cmake") target_include_directories(SDL PRIVATE ${SDL2_INCLUDE_DIRS}) From 90c4b0f38fff3070fec04ca747ecb9869b533b66 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Tue, 27 Sep 2022 03:32:42 +0200 Subject: [PATCH 368/606] cmake: find SDL2 using find_package --- CMakeLists.txt | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b3400d78a..c3ca347ab 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,6 +15,10 @@ if(STATICDEVEL AND NOT (CMAKE_SYSTEM_NAME MATCHES "Linux")) MESSAGE(FATAL_ERROR "Static builds are only supported on Linux.") endif() +list(APPEND CMAKE_MODULE_PATH + "${CMAKE_CURRENT_LIST_DIR}/cmake/modules" +) + include(CheckCSourceCompiles) include(CheckIncludeFile) include(CheckCCompilerFlag) @@ -48,7 +52,10 @@ set(SDL12COMPAT_SRCS ) add_library(SDL SHARED ${SDL12COMPAT_SRCS}) -include("cmake/modules/FindSDL2.cmake") +find_package(SDL2) +if(NOT SDL2_INCLUDE_DIRS) + message(FATAL_ERROR "Could not find SDL2 headers") +endif() target_include_directories(SDL PRIVATE ${SDL2_INCLUDE_DIRS}) set(EXTRA_CFLAGS ) From 26143790b57a44446564b45734e20deacf687448 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Tue, 27 Sep 2022 03:33:52 +0200 Subject: [PATCH 369/606] cmake: lowercase all functions in CMakeLists.txt --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c3ca347ab..43d5e7c35 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,7 +12,7 @@ option(SDL12DEVEL "Enable installing SDL-1.2 development headers" ON) option(STATICDEVEL "Enable installing static link library" OFF) if(STATICDEVEL AND NOT (CMAKE_SYSTEM_NAME MATCHES "Linux")) - MESSAGE(FATAL_ERROR "Static builds are only supported on Linux.") + message(FATAL_ERROR "Static builds are only supported on Linux.") endif() list(APPEND CMAKE_MODULE_PATH From 81d788ec0a7569aa4c460f493aba13caed8c0233 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Tue, 27 Sep 2022 03:42:20 +0200 Subject: [PATCH 370/606] cmake: add CMAKE_DL_LIBS using a for loop prepending each with -l --- CMakeLists.txt | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 43d5e7c35..226222283 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -102,7 +102,7 @@ elseif(WIN32) set_target_properties(SDL PROPERTIES VERSION "${PROJECT_VERSION}" SOVERSION "0" - OUTPUT_NAME "SDL") + OUTPUT_NAME "SDL") elseif(OS2) set_target_properties(SDL PROPERTIES COMPILE_DEFINITIONS "BUILD_SDL") # for DECLSPEC set_target_properties(SDL PROPERTIES @@ -113,7 +113,7 @@ else() set_target_properties(SDL PROPERTIES VERSION "${PROJECT_VERSION}" SOVERSION "0" - OUTPUT_NAME "SDL") + OUTPUT_NAME "SDL") endif() if(MINGW) @@ -262,7 +262,10 @@ if(SDL12DEVEL) set(SDL_CFLAGS "-D_GNU_SOURCE=1 -D_REENTRANT") set(SDL_RLD_FLAGS "") # !!! FIXME: this forces rpath, which we might want? set(SDL_LIBS "-lSDL") - set(SDL_STATIC_LIBS ${CMAKE_DL_LIBS}) + set(SDL_STATIC_LIBS "") + foreach(lib ${CMAKE_DL_LIBS}) + set(SDL_STATIC_LIBS "-l${lib}") + endforeach() if(NOT STATICDEVEL) set(SDL_STATIC_LIBS "") endif() From cf8c44a6706ffb9f34172419c9812f943c09b688 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Tue, 27 Sep 2022 07:28:00 +0300 Subject: [PATCH 371/606] remove an extra empty line. --- CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 226222283..5fb31b18e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -141,7 +141,6 @@ return 0; }" IS_X86) endforeach(flag_var) endif() - # SDLmain library... if(APPLE) add_library(SDLmain STATIC src/SDLmain/macosx/SDLMain.m) From cff5d80e379909714ee7a643919bb2470f26a81e Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Tue, 27 Sep 2022 18:56:10 +0300 Subject: [PATCH 372/606] Video driver name tweaks for windows. Fixes: https://github.com/libsdl-org/sdl12-compat/issues/223 --- src/SDL12_compat.c | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 5ee543bd5..ff1e9951b 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -2324,9 +2324,15 @@ SDL_InitSubSystem(Uint32 sdl12flags) backend, but it doesn't exist in SDL2. Force to "windows" instead. */ const char *origvidenv = NULL; const char *env = SDL20_getenv("SDL_VIDEODRIVER"); - if (env && (SDL20_strcmp(env, "windib") == 0)) { - origvidenv = "windib"; - SDL20_setenv("SDL_VIDEODRIVER", "windows", 1); + if (env) { + if (SDL20_strcmp(env, "windib") == 0) { + origvidenv = "windib"; + SDL20_setenv("SDL_VIDEODRIVER", "windows", 1); + } else + if (SDL20_strcmp(env, "directx") == 0) { + origvidenv = "directx"; + SDL20_setenv("SDL_VIDEODRIVER", "windows", 1); + } } #endif @@ -2599,7 +2605,26 @@ SDL_AudioDriverName(char *namebuf, int maxlen) DECLSPEC12 const char * SDLCALL SDL_VideoDriverName(char *namebuf, int maxlen) { +#ifdef __WINDOWS__ + const char *val = SDL20_getenv("SDL_VIDEODRIVER"); + if (val) { + /* give them back what they requested: */ + if (SDL20_strcmp(val, "windib") == 0 || + SDL20_strcmp(val, "directx") == 0) { + return GetDriverName(val, namebuf, maxlen); + } + } + val = SDL20_GetCurrentVideoDriver(); + if (val && SDL20_strcmp(val, "windows") == 0) { + /* Windows apps may use SDL_VideoDriverName() to check accelerated + * vs unaccelerated display by using directx and windib. + * https://github.com/libsdl-org/sdl12-compat/issues/223 */ + val = "directx"; + } + return GetDriverName(val, namebuf, maxlen); +#else return GetDriverName(SDL20_GetCurrentVideoDriver(), namebuf, maxlen); +#endif } From 50bde9f51d5e1714fdd87d380a030b28ce6a2cf1 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 28 Sep 2022 13:18:38 -0400 Subject: [PATCH 373/606] events: Mousewheels need to report current mouse position. Reference issue #215. --- src/SDL12_compat.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index ff1e9951b..3c9272fc5 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -4616,8 +4616,8 @@ EventFilter20to12(void *data, SDL_Event *event20) event12.button.which = (Uint8) event20->wheel.which; event12.button.button = (event20->wheel.y > 0) ? 4 : 5; /* wheelup is 4, down is 5. */ event12.button.state = SDL_PRESSED; - event12.button.x = 0; - event12.button.y = 0; + event12.button.x = MousePosition.x; + event12.button.y = MousePosition.y; PushEventIfNotFiltered(&event12); event12.type = SDL12_MOUSEBUTTONUP; /* immediately release mouse "button" at the end of this switch. */ From 3fac63ac783bdb40f724ab22ceb5cca5d1bb8adb Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 30 Sep 2022 11:07:55 -0400 Subject: [PATCH 374/606] SDL_config.h: Define HAVE_STRLCPY on some platforms. This makes 1.2 apps compiled with sdl12-compat's headers work with a real SDL 1.2 library on macOS. Otherwise: missing symbol. --- include/SDL/SDL_config.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/SDL/SDL_config.h b/include/SDL/SDL_config.h index 7b832a0e8..d76b2de08 100644 --- a/include/SDL/SDL_config.h +++ b/include/SDL/SDL_config.h @@ -133,7 +133,6 @@ stage, though. Send patches if your platform lacks something. */ #define HAVE_BCOPY 1 #define HAVE_ATOI 1 #define HAVE_ATOF 1 -#define HAVE_STRLCPY 1 #define HAVE_STRLCAT 1 #define HAVE__STRREV 1 #define HAVE__STRUPR 1 @@ -166,6 +165,10 @@ stage, though. Send patches if your platform lacks something. */ #define HAVE_SETJMP 1 #endif +#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) /* macos and BSDs have this. */ +#define HAVE_STRLCPY 1 +#endif + /* Don't define most of the SDL backends, under the assumption checking for these against the headers won't work anyhow. The exception is the X11 backend; you need its define to know if you can use its syswm interface. */ From 9618d03fee48f31ccb623a8210e4e94c534189ff Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 30 Sep 2022 15:22:58 -0400 Subject: [PATCH 375/606] events: Drop mouse motion if screen surface isn't available yet. Reference Issue #215. --- src/SDL12_compat.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 3c9272fc5..796d7b539 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -4533,6 +4533,10 @@ EventFilter20to12(void *data, SDL_Event *event20) } case SDL_MOUSEMOTION: + if (!VideoSurface12) { + return 1; /* we don't have a screen surface yet? Don't send this on to the app. */ + } + event12.type = SDL12_MOUSEMOTION; event12.motion.which = (Uint8) event20->motion.which; event12.motion.state = event20->motion.state; From e4cf630ef35dcb35bfaadde5213a9db13367cef8 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 30 Sep 2022 20:53:33 -0400 Subject: [PATCH 376/606] Bumped version to 1.2.58 for prerelease! --- CMakeLists.txt | 4 ++-- include/SDL/SDL_version.h | 2 +- src/Makefile.darwin | 2 +- src/Makefile.linux | 2 +- src/Makefile.os2 | 2 +- src/Makefile.w32 | 2 +- src/SDL12_compat.c | 2 +- src/version.rc | 8 ++++---- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5fb31b18e..bdaf027ae 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.0.0) project(sdl12_compat - VERSION 1.2.56 + VERSION 1.2.58 LANGUAGES C) option(SDL12TESTS "Enable to build SDL-1.2 test programs" ON) @@ -33,7 +33,7 @@ if(APPLE) # Xcode project file uses 1.0.0, but it's more compatible to use the # higher version. set(DYLIB_COMPAT_VERSION 12.0.0 CACHE STRING "library compatibility version") - set(DYLIB_CURRENT_VERSION 12.56.0 CACHE STRING "library current version") + set(DYLIB_CURRENT_VERSION 12.58.0 CACHE STRING "library current version") include_directories("/opt/X11/include") # hack. if(CMAKE_VERSION VERSION_LESS 3.9) else() diff --git a/include/SDL/SDL_version.h b/include/SDL/SDL_version.h index a5efe8a5f..010f8a1b8 100644 --- a/include/SDL/SDL_version.h +++ b/include/SDL/SDL_version.h @@ -33,7 +33,7 @@ real SDL-1.2 available to you. */ /* We bumped the patchlevel to 50 for sdl12-compat */ #define SDL_MAJOR_VERSION 1 #define SDL_MINOR_VERSION 2 -#define SDL_PATCHLEVEL 56 +#define SDL_PATCHLEVEL 58 typedef struct SDL_version { diff --git a/src/Makefile.darwin b/src/Makefile.darwin index f2368508c..ce933661f 100644 --- a/src/Makefile.darwin +++ b/src/Makefile.darwin @@ -18,7 +18,7 @@ CFLAGS = -mmacosx-version-min=10.6 -fPIC -O3 -Wall LDFLAGS = -mmacosx-version-min=10.6 -dynamiclib -Wl,-undefined,error -Wl,-single_module #LDFLAGS+= -Wl,-headerpad_max_install_names LDFLAGS+= -Wl,-install_name,"/usr/local/lib/$(DYLIB)" -LDFLAGS+= -Wl,-compatibility_version,1.0 -Wl,-current_version,12.56 +LDFLAGS+= -Wl,-compatibility_version,1.0 -Wl,-current_version,12.58 LDLIBS = -Wl,-framework,AppKit # this is needed for x86_64 - cross-gcc might not add it. #LDLIBS += -Wl,-lbundle1.o diff --git a/src/Makefile.linux b/src/Makefile.linux index 29f56dbda..db7dc1aec 100644 --- a/src/Makefile.linux +++ b/src/Makefile.linux @@ -16,7 +16,7 @@ LDFLAGS = -shared -Wl,-soname,libSDL-1.2.so.0 LDFLAGS+= -Wl,--no-undefined LDLIBS = -ldl -SHLIB = libSDL-1.2.so.1.2.56 +SHLIB = libSDL-1.2.so.1.2.58 OBJ = SDL12_compat.o diff --git a/src/Makefile.os2 b/src/Makefile.os2 index ce4096ecb..d39e21877 100644 --- a/src/Makefile.os2 +++ b/src/Makefile.os2 @@ -5,7 +5,7 @@ !endif DLLNAME = SDL12 -VERSION = 1.2.56 +VERSION = 1.2.58 # change SDL2INC to point to the SDL2 headers SDL2INC = include diff --git a/src/Makefile.w32 b/src/Makefile.w32 index 2f05d52c6..592ff6c1c 100644 --- a/src/Makefile.w32 +++ b/src/Makefile.w32 @@ -5,7 +5,7 @@ !endif DLLNAME = SDL -VERSION = 1.2.56 +VERSION = 1.2.58 # change SDL2INC to point to the SDL2 headers SDL2INC = include diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 796d7b539..dbab523ed 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -28,7 +28,7 @@ * should be way ahead of what SDL-1.2 Classic would report, so apps can * decide if they're running under the compat layer, if they really care. */ -#define SDL12_COMPAT_VERSION 56 +#define SDL12_COMPAT_VERSION 58 #include #include diff --git a/src/version.rc b/src/version.rc index 678e85b19..abf819210 100644 --- a/src/version.rc +++ b/src/version.rc @@ -3,8 +3,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,2,56,0 - PRODUCTVERSION 1,2,56,0 + FILEVERSION 1,2,58,0 + PRODUCTVERSION 1,2,58,0 FILEFLAGSMASK 0x3fL FILEFLAGS 0x0L FILEOS 0x40004L @@ -17,12 +17,12 @@ BEGIN BEGIN VALUE "CompanyName", "\0" VALUE "FileDescription", "SDL\0" - VALUE "FileVersion", "1, 2, 56, 0\0" + VALUE "FileVersion", "1, 2, 58, 0\0" VALUE "InternalName", "SDL\0" VALUE "LegalCopyright", "Copyright © 2022 Sam Lantinga\0" VALUE "OriginalFilename", "SDL.dll\0" VALUE "ProductName", "Simple DirectMedia Layer 1.2 wrapper\0" - VALUE "ProductVersion", "1, 2, 56, 0\0" + VALUE "ProductVersion", "1, 2, 58, 0\0" END END BLOCK "VarFileInfo" From fb94bb41eb78a43907bacf0df437bdb877d8ab6d Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 30 Sep 2022 21:09:41 -0400 Subject: [PATCH 377/606] Bump version to 1.2.59 for anything between prerelease and final. --- CMakeLists.txt | 4 ++-- include/SDL/SDL_version.h | 2 +- src/Makefile.darwin | 2 +- src/Makefile.linux | 2 +- src/Makefile.os2 | 2 +- src/Makefile.w32 | 2 +- src/SDL12_compat.c | 2 +- src/version.rc | 8 ++++---- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bdaf027ae..0ea691415 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.0.0) project(sdl12_compat - VERSION 1.2.58 + VERSION 1.2.59 LANGUAGES C) option(SDL12TESTS "Enable to build SDL-1.2 test programs" ON) @@ -33,7 +33,7 @@ if(APPLE) # Xcode project file uses 1.0.0, but it's more compatible to use the # higher version. set(DYLIB_COMPAT_VERSION 12.0.0 CACHE STRING "library compatibility version") - set(DYLIB_CURRENT_VERSION 12.58.0 CACHE STRING "library current version") + set(DYLIB_CURRENT_VERSION 12.59.0 CACHE STRING "library current version") include_directories("/opt/X11/include") # hack. if(CMAKE_VERSION VERSION_LESS 3.9) else() diff --git a/include/SDL/SDL_version.h b/include/SDL/SDL_version.h index 010f8a1b8..15d797fb3 100644 --- a/include/SDL/SDL_version.h +++ b/include/SDL/SDL_version.h @@ -33,7 +33,7 @@ real SDL-1.2 available to you. */ /* We bumped the patchlevel to 50 for sdl12-compat */ #define SDL_MAJOR_VERSION 1 #define SDL_MINOR_VERSION 2 -#define SDL_PATCHLEVEL 58 +#define SDL_PATCHLEVEL 59 typedef struct SDL_version { diff --git a/src/Makefile.darwin b/src/Makefile.darwin index ce933661f..6e1487864 100644 --- a/src/Makefile.darwin +++ b/src/Makefile.darwin @@ -18,7 +18,7 @@ CFLAGS = -mmacosx-version-min=10.6 -fPIC -O3 -Wall LDFLAGS = -mmacosx-version-min=10.6 -dynamiclib -Wl,-undefined,error -Wl,-single_module #LDFLAGS+= -Wl,-headerpad_max_install_names LDFLAGS+= -Wl,-install_name,"/usr/local/lib/$(DYLIB)" -LDFLAGS+= -Wl,-compatibility_version,1.0 -Wl,-current_version,12.58 +LDFLAGS+= -Wl,-compatibility_version,1.0 -Wl,-current_version,12.59 LDLIBS = -Wl,-framework,AppKit # this is needed for x86_64 - cross-gcc might not add it. #LDLIBS += -Wl,-lbundle1.o diff --git a/src/Makefile.linux b/src/Makefile.linux index db7dc1aec..183bff4db 100644 --- a/src/Makefile.linux +++ b/src/Makefile.linux @@ -16,7 +16,7 @@ LDFLAGS = -shared -Wl,-soname,libSDL-1.2.so.0 LDFLAGS+= -Wl,--no-undefined LDLIBS = -ldl -SHLIB = libSDL-1.2.so.1.2.58 +SHLIB = libSDL-1.2.so.1.2.59 OBJ = SDL12_compat.o diff --git a/src/Makefile.os2 b/src/Makefile.os2 index d39e21877..39cbf72f1 100644 --- a/src/Makefile.os2 +++ b/src/Makefile.os2 @@ -5,7 +5,7 @@ !endif DLLNAME = SDL12 -VERSION = 1.2.58 +VERSION = 1.2.59 # change SDL2INC to point to the SDL2 headers SDL2INC = include diff --git a/src/Makefile.w32 b/src/Makefile.w32 index 592ff6c1c..fc95a8e43 100644 --- a/src/Makefile.w32 +++ b/src/Makefile.w32 @@ -5,7 +5,7 @@ !endif DLLNAME = SDL -VERSION = 1.2.58 +VERSION = 1.2.59 # change SDL2INC to point to the SDL2 headers SDL2INC = include diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index dbab523ed..a2c1aadd1 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -28,7 +28,7 @@ * should be way ahead of what SDL-1.2 Classic would report, so apps can * decide if they're running under the compat layer, if they really care. */ -#define SDL12_COMPAT_VERSION 58 +#define SDL12_COMPAT_VERSION 59 #include #include diff --git a/src/version.rc b/src/version.rc index abf819210..0ed2e2fb7 100644 --- a/src/version.rc +++ b/src/version.rc @@ -3,8 +3,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,2,58,0 - PRODUCTVERSION 1,2,58,0 + FILEVERSION 1,2,59,0 + PRODUCTVERSION 1,2,59,0 FILEFLAGSMASK 0x3fL FILEFLAGS 0x0L FILEOS 0x40004L @@ -17,12 +17,12 @@ BEGIN BEGIN VALUE "CompanyName", "\0" VALUE "FileDescription", "SDL\0" - VALUE "FileVersion", "1, 2, 58, 0\0" + VALUE "FileVersion", "1, 2, 59, 0\0" VALUE "InternalName", "SDL\0" VALUE "LegalCopyright", "Copyright © 2022 Sam Lantinga\0" VALUE "OriginalFilename", "SDL.dll\0" VALUE "ProductName", "Simple DirectMedia Layer 1.2 wrapper\0" - VALUE "ProductVersion", "1, 2, 58, 0\0" + VALUE "ProductVersion", "1, 2, 59, 0\0" END END BLOCK "VarFileInfo" From 39374a31358df9913ad604098fd1809f24440b40 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Mon, 3 Oct 2022 10:36:39 +0100 Subject: [PATCH 378/606] README: Mention the ALLOW_THREADED_ quirks Signed-off-by: Simon McVittie --- README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/README.md b/README.md index 201740d72..0bab46856 100644 --- a/README.md +++ b/README.md @@ -246,6 +246,18 @@ The available options are: applications which use their own mouse cursors. See also: https://wiki.libsdl.org/SDL_HINT_MOUSE_RELATIVE_SCALING +- SDL12COMPAT_ALLOW_THREADED_DRAWS: (checked during SDL_Init) + Enabled by default. + If disabled, calls to `SDL_UpdateRects()` from non-main threads are + converted into requests for the main thread to carry out the update later. + The thread that called `SDL_SetVideoMode()` is treated as the main thread. + +- SDL12COMPAT_ALLOW_THREADED_PUMPS: (checked during SDL_Init) + Enabled by default. + If disabled, calls to `SDL_PumpEvents()` from non-main threads are + completely ignored. + The thread that called `SDL_SetVideoMode()` is treated as the main thread. + # Compatibility issues with OpenGL scaling The OpenGL scaling feature of sdl12-compat allows applications which wish to From e9131f26205a539f35fd5dbdcc9678c031374f1f Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 3 Oct 2022 20:41:04 -0400 Subject: [PATCH 379/606] video: SDL_VideoModeOK shouldn't require exact dimensions. 1.2 (on many video backends) would allow smaller surfaces that it would center in a larger mode, so emulate that here. Reference Issue #228. --- src/SDL12_compat.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index a2c1aadd1..75dd2da8a 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -5117,16 +5117,21 @@ SDL_VideoModeOK(int width, int height, int bpp, Uint32 sdl12flags) return 0; } + /* if the 1.2 video backend could center a surface in a larger mode, it + would accept the size. Since we scale things, we will, too, even + without an exact width/height match. */ + if (!(sdl12flags & SDL12_FULLSCREEN)) { SDL_DisplayMode mode; SDL20_GetDesktopDisplayMode(VideoDisplayIndex, &mode); - actual_bpp = SDL_BITSPERPIXEL(mode.format); + if ((mode.w >= width) && (mode.h >= height)) { + actual_bpp = SDL_BITSPERPIXEL(mode.format); + } } else { for (i = 0; i < VideoModesCount; ++i) { VideoModeList *vmode = &VideoModes[i]; for (j = 0; j < vmode->nummodes; ++j) { - if (vmode->modeslist12[j].w == width && vmode->modeslist12[j].h == height) - { + if (vmode->modeslist12[j].w >= width && vmode->modeslist12[j].h >= height) { if (!vmode->format) { return bpp; } From 14465fc12c33430475af7e10886e2230192e6a41 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 3 Oct 2022 20:38:49 -0400 Subject: [PATCH 380/606] audio: SDL_OpenAudio must init the subsystem if necessary. Reference Issue #228. --- src/SDL12_compat.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 75dd2da8a..f93c6bd60 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -9030,6 +9030,13 @@ SDL_OpenAudio(SDL_AudioSpec *want, SDL_AudioSpec *obtained) { SDL_bool already_opened; + /* SDL_OpenAudio() will init the subsystem for you if necessary, yuck. */ + if ((InitializedSubsystems20 & SDL_INIT_AUDIO) != SDL_INIT_AUDIO) { + if (SDL_InitSubSystem(SDL12_INIT_AUDIO) < 0) { + return -1; + } + } + /* SDL2 uses a NULL callback to mean "we plan to use SDL_QueueAudio()" */ if (want && (want->callback == NULL)) { return SDL20_SetError("Callback can't be NULL"); From 3c80688bbedb336879619199feac05234f9b97a3 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 3 Oct 2022 20:40:22 -0400 Subject: [PATCH 381/606] audio: SDL_MixAudio has to respect app format, which we might be faking. Fixes #228. --- src/SDL12_compat.c | 34 ++++++++++++++++++++++++++++++++-- src/SDL20_include_wrapper.h | 2 ++ src/SDL20_syms.h | 2 +- 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index f93c6bd60..db151fe1a 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -8844,7 +8844,7 @@ FakeCdRomAudioCallback(AudioCallbackWrapperData *data, Uint8 *stream, int len, c SDL20_AudioStreamGet(data->cdrom_stream, stream, available); } else { SDL20_AudioStreamGet(data->cdrom_stream, data->mix_buffer, available); - SDL20_MixAudio(stream, data->mix_buffer, available, SDL_MIX_MAXVOLUME); + SDL20_MixAudioFormat(stream, data->mix_buffer, audio_cbdata->device_format.format, available, SDL_MIX_MAXVOLUME); } data->cdrom_pcm_frames_written += (int) ((available / ((double) SDL_AUDIO_BITSIZE(data->device_format.format) / 8.0)) / data->device_format.channels); @@ -9152,6 +9152,37 @@ SDL_GetAudioStatus(void) return retval; } +DECLSPEC12 void SDLCALL +SDL_MixAudio(Uint8 *dst, const Uint8 *src, Uint32 len, int volume) +{ + SDL_AudioFormat fmt; + + if (volume == 0) { + return; /* nothing to do. */ + } + + /* in 1.2, if not the subsystem isn't initialized _at all_, it forces + format to AUDIO_S16. If it's initialized but the device isn't opened, + you get a format of zero and it returns an error without mixing + anything. */ + SDL20_LockAudio(); + if ((InitializedSubsystems20 & SDL_INIT_AUDIO) != SDL_INIT_AUDIO) { + fmt = AUDIO_S16; /* to quote 1.2: "HACK HACK HACK" */ + } else if (!audio_cbdata || !audio_cbdata->app_callback_opened) { + fmt = 0; /* this will fail, but drop the lock first. */ + } else { + fmt = audio_cbdata->app_callback_format.format; + } + SDL20_UnlockAudio(); + + if (fmt == 0) { + SDL_SetError("SDL_MixAudio(): unknown audio format"); /* this is the exact error 1.2 reports for this. */ + } else { + SDL20_MixAudioFormat(dst, src, fmt, len, volume); + } +} + + DECLSPEC12 void SDLCALL SDL_CloseAudio(void) { @@ -9166,7 +9197,6 @@ SDL_CloseAudio(void) CloseSDL2AudioDevice(); } - static SDL_AudioCVT * AudioCVT12to20(const SDL12_AudioCVT *cvt12, SDL_AudioCVT *cvt20) { diff --git a/src/SDL20_include_wrapper.h b/src/SDL20_include_wrapper.h index 4d4be2220..adea80acc 100644 --- a/src/SDL20_include_wrapper.h +++ b/src/SDL20_include_wrapper.h @@ -113,6 +113,7 @@ #define SDL_VideoInit IGNORE_THIS_VERSION_OF_SDL_VideoInit #define SDL_BuildAudioCVT IGNORE_THIS_VERSION_OF_SDL_BuildAudioCVT #define SDL_ConvertAudio IGNORE_THIS_VERSION_OF_SDL_ConvertAudio +#define SDL_MixAudio IGNORE_THIS_VERSION_OF_SDL_MixAudio #define SDL_RegisterApp IGNORE_THIS_VERSION_OF_SDL_RegisterApp #define SDL_UnregisterApp IGNORE_THIS_VERSION_OF_SDL_UnregisterApp @@ -242,6 +243,7 @@ typedef void (__cdecl *pfnSDL_CurrentEndThread) (unsigned); #undef SDL_VideoInit #undef SDL_BuildAudioCVT #undef SDL_ConvertAudio +#undef SDL_MixAudio #undef SDL_RegisterApp #undef SDL_UnregisterApp diff --git a/src/SDL20_syms.h b/src/SDL20_syms.h index e5469b8b5..cb54bdf0e 100644 --- a/src/SDL20_syms.h +++ b/src/SDL20_syms.h @@ -206,7 +206,7 @@ SDL20_SYM(void,PauseAudio,(int a),(a),) SDL20_SYM_PASSTHROUGH(void,FreeWAV,(Uint8 *a),(a),) SDL20_SYM(int,BuildAudioCVT,(SDL_AudioCVT *a, Uint16 b, Uint8 c, int d, Uint16 e, Uint8 f, int g),(a,b,c,d,e,f,g),return) SDL20_SYM(int,ConvertAudio,(SDL_AudioCVT *a),(a),return) -SDL20_SYM_PASSTHROUGH(void,MixAudio,(Uint8 *a, const Uint8 *b, Uint32 c, int d),(a,b,c,d),) +SDL20_SYM(void,MixAudioFormat,(Uint8 *a, const Uint8 *b, SDL_AudioFormat c, Uint32 d, int e),(a,b,c,d,e),) SDL20_SYM_PASSTHROUGH(void,LockAudio,(void),(),) SDL20_SYM_PASSTHROUGH(void,UnlockAudio,(void),(),) From a3611abb7a98d14c0e5d61eea1d7818e719f2335 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 3 Oct 2022 20:53:47 -0400 Subject: [PATCH 382/606] video: Deal with dest alpha save/restore of full (NULL) dstrect. Reference Issue #230. --- src/SDL12_compat.c | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index db151fe1a..4c545b635 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -6162,15 +6162,23 @@ SaveDestAlpha(SDL12_Surface *src12, SDL12_Surface *dst12, const SDL12_Rect *dstr const SDL_bool save_dstalpha = ((src12->flags & SDL12_SRCALPHA) && dst12->format->Amask && ((src12->format->alpha != 255) || src12->format->Amask)) ? SDL_TRUE : SDL_FALSE; if (save_dstalpha) { - Uint8 *dptr; - int x, y; - - const int w = dstrect12->w; - const int h = dstrect12->h; - const Uint32 amask = dst12->format->Amask; const Uint32 ashift = dst12->format->Ashift; const Uint16 pitch = dst12->pitch; + SDL12_Rect fullrect; + Uint8 *dptr; + int x, y, w, h; + + if (!dstrect12) { + fullrect.x = 0; + fullrect.y = 0; + fullrect.w = dst12->w; + fullrect.h = dst12->h; + dstrect12 = &fullrect; + } + + w = dstrect12->w; + h = dstrect12->h; dstalpha = (Uint8 *) SDL20_malloc(w * h); if (!dstalpha) { @@ -6210,14 +6218,23 @@ static void RestoreDestAlpha(SDL12_Surface *dst12, Uint8 *dstalpha, const SDL12_Rect *dstrect12) { if (dstalpha) { - int x, y; - - const int w = dstrect12->w; - const int h = dstrect12->h; const Uint8 *sptr = dstalpha; const Uint32 amask = dst12->format->Amask; const Uint32 ashift = dst12->format->Ashift; const Uint16 pitch = dst12->pitch; + SDL12_Rect fullrect; + int x, y, w, h; + + if (!dstrect12) { + fullrect.x = 0; + fullrect.y = 0; + fullrect.w = dst12->w; + fullrect.h = dst12->h; + dstrect12 = &fullrect; + } + + w = dstrect12->w; + h = dstrect12->h; if (dst12->format->BytesPerPixel == 2) { Uint16 *dptr = (Uint16 *) dst12->pixels; From 41030f3df3ad699dd4a6735c4677a371c9f33cd5 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 3 Oct 2022 21:29:48 -0400 Subject: [PATCH 383/606] debug: Debug logging now reports the sdl12-compat version ("1.2.x"). --- src/SDL12_compat.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 4c545b635..a40e7e1a8 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1356,9 +1356,9 @@ LoadSDL20(void) WantDebugLogging = SDL12Compat_GetHintBoolean("SDL12COMPAT_DEBUG_LOGGING", SDL_FALSE); if (WantDebugLogging) { #if defined(__DATE__) && defined(__TIME__) - SDL20_Log("sdl12-compat, built on " __DATE__ " at " __TIME__ ", talking to SDL2 %d.%d.%d", v.major, v.minor, v.patch); + SDL20_Log("sdl12-compat 1.2.%d, built on " __DATE__ " at " __TIME__ ", talking to SDL2 %d.%d.%d", SDL12_COMPAT_VERSION, v.major, v.minor, v.patch); #else - SDL20_Log("sdl12-compat, talking to SDL2 %d.%d.%d", v.major, v.minor, v.patch); + SDL20_Log("sdl12-compat 1.2.%d, talking to SDL2 %d.%d.%d", SDL12_COMPAT_VERSION, v.major, v.minor, v.patch); #endif } SDL12Compat_ApplyQuirks(); /* Apply and maybe print a list of any enabled quirks. */ From 4fc061cd35ec12b296b96a160923e08fa2c2d0b4 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 4 Oct 2022 15:01:52 -0400 Subject: [PATCH 384/606] video: SDL_UpdateRects must own the renderer to touch the screen texture. Fixes #230. --- src/SDL12_compat.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index a40e7e1a8..3c69b953e 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -6656,15 +6656,20 @@ SDL_UpdateRects(SDL12_Surface *surface12, int numrects, SDL12_Rect *rects12) const int pixsize = surface12->format->BytesPerPixel; const int srcpitch = surface12->pitch; SDL_bool whole_screen = SDL_FALSE; + SDL_Renderer *renderer = NULL; void *pixels = NULL; SDL_Rect rect20; int pitch = 0; int i, j; + if (!upload_later) { + renderer = LockVideoRenderer(); /* must own the renderer before locking the texture! */ + } + for (i = 0; i < numrects; i++) { UpdateRect12to20(surface12, &rects12[i], &rect20, &whole_screen); - if (upload_later) { + if (!renderer) { continue; } else if (!rect20.w || !rect20.h) { continue; @@ -6711,6 +6716,10 @@ SDL_UpdateRects(SDL12_Surface *surface12, int numrects, SDL12_Rect *rects12) } else { VideoSurfacePresentTicks = VideoSurfaceLastPresentTicks + GetDesiredMillisecondsPerFrame(); /* flip it later. */ } + + if (renderer) { + UnlockVideoRenderer(); + } } } From eba13ef98d0f6f827e541fee00363174e048d6dc Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 5 Oct 2022 14:05:32 -0400 Subject: [PATCH 385/606] quirks: Civ:CTP no longer needs quirks to function! It was actually fixed by 4fc061cd35ec12b296b96a160923e08fa2c2d0b4 ! --- src/SDL12_compat.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 3c69b953e..dc230f3a5 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1206,14 +1206,6 @@ static QuirkEntryType quirks[] = { {"tucnak", "SDL_RENDER_DRIVER", "software"}, {"tucnak", "SDL_FRAMEBUFFER_ACCELERATION", "false"}, - /* Civilization: Call to Power draws and pumps from multiple threads at once, causing issues. */ - {"civctp", "SDL12COMPAT_ALLOW_THREADED_DRAWS", "0"}, - {"civctp", "SDL12COMPAT_ALLOW_THREADED_PUMPS", "0"}, - {"civctp.dynamic", "SDL12COMPAT_ALLOW_THREADED_DRAWS", "0"}, - {"civctp.dynamic", "SDL12COMPAT_ALLOW_THREADED_PUMPS", "0"}, - {"civctp.dynamic_fixed", "SDL12COMPAT_ALLOW_THREADED_DRAWS", "0"}, - {"civctp.dynamic_fixed", "SDL12COMPAT_ALLOW_THREADED_PUMPS", "0"}, - /* The 32-bit Steam build only of Multiwinia Quits but doesn't re-Init */ {"multiwinia.bin.x86", "SDL12COMPAT_NO_QUIT_VIDEO", "1"} #else From f388224779a924108d97596e039d07b5fad7f2a6 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 6 Oct 2022 23:44:02 -0400 Subject: [PATCH 386/606] events: Don't send SDL_VIDEOEXPOSE events during window creation. SDL 1.2 doesn't do so either, at least on X11, and doing so triggers a bug in Bloboats, so we'll avoid it to try to maximize compatibility. Fixes #229. --- src/SDL12_compat.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index dc230f3a5..a7dfa5c30 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -948,6 +948,7 @@ static SDL12_PixelFormat VideoInfoVfmt12; static SDL_PixelFormat *VideoInfoVfmt20 = NULL; static SDL_bool VideoWindowGrabbed = SDL_FALSE; static SDL_bool VideoCursorHidden = SDL_FALSE; +static SDL_bool SetVideoModeInProgress = SDL_FALSE; static SDL_Window *VideoWindow20 = NULL; static SDL_Renderer *VideoRenderer20 = NULL; static SDL_mutex *VideoRendererLock = NULL; @@ -4334,7 +4335,10 @@ EventFilter20to12(void *data, SDL_Event *event20) case SDL_WINDOWEVENT_SHOWN: case SDL_WINDOWEVENT_EXPOSED: - event12.type = SDL12_VIDEOEXPOSE; + /* drop these during window creation (see issue #229) */ + if (!SetVideoModeInProgress) { + event12.type = SDL12_VIDEOEXPOSE; + } break; case SDL_WINDOWEVENT_RESIZED: { @@ -5695,8 +5699,8 @@ UnlockVideoRenderer(void) static void HandleInputGrab(SDL12_GrabMode mode); -DECLSPEC12 SDL12_Surface * SDLCALL -SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12) +static SDL12_Surface * +SetVideoModeImpl(int width, int height, int bpp, Uint32 flags12) { SDL_DisplayMode dmode; Uint32 fullscreen_flags20 = 0; @@ -6130,9 +6134,21 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12) UnlockVideoRenderer(); } + SDL_PumpEvents(); /* run this once at startup. */ + return VideoSurface12; } +DECLSPEC12 SDL12_Surface * SDLCALL +SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12) +{ + SDL12_Surface *retval; + SetVideoModeInProgress = SDL_TRUE; + retval = SetVideoModeImpl(width, height, bpp, flags12); + SetVideoModeInProgress = SDL_FALSE; + return retval; +} + DECLSPEC12 SDL12_Surface * SDLCALL SDL_GetVideoSurface(void) { From 9ff63b728f2cb0f844edccf9fcc2f99c0d6b23e3 Mon Sep 17 00:00:00 2001 From: David Gow Date: Sat, 8 Oct 2022 21:22:03 +0800 Subject: [PATCH 387/606] cdrom: Fix end offset calulcation in SDL_CDPlay We were accidentally using the frame number instead of the track number to lookup a track, which not only resulted in playback cutting off in the middle of tracks, but also probably accessed a bunch of invalid memory. --- src/SDL12_compat.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index a7dfa5c30..a49b1f9b1 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -8701,12 +8701,12 @@ SDL_CDPlay(SDL12_CD *cdrom, int start, int length) start_frame = start - cdrom->track[start_track].offset; - if (remain < (cdrom->track[start_frame].length - start_frame)) { + if (remain < (cdrom->track[start_track].length - start_frame)) { ntracks = 0; nframes = remain; remain = 0; } else { - remain -= (cdrom->track[start_frame].length - start_frame); + remain -= (cdrom->track[start_track].length - start_frame); for (i = start_track + 1; i < cdrom->numtracks; i++) { if (remain < cdrom->track[i].length) { ntracks = i - start_track; From 557bb05398d5508c2f899c0774e2240a71ae5f58 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 10 Oct 2022 13:52:10 -0400 Subject: [PATCH 388/606] testwm: More robust SDL12COMPAT_GetWindow() testing. --- test/testwm.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/test/testwm.c b/test/testwm.c index ced2981d8..16f29bfa5 100644 --- a/test/testwm.c +++ b/test/testwm.c @@ -348,7 +348,6 @@ int SDLCALL FilterEvents(const SDL_Event *event) } } - static char testtitle[] = "Testing 1.. 2.. 3..."; int main(int argc, char *argv[]) @@ -458,10 +457,17 @@ int main(int argc, char *argv[]) printf("Generic syswm info: data=%X\n", syswm_info.data); #endif } -#if SDL_COMPILEDVERSION >= SDL_VERSIONNUM(1, 2, 54) - printf("SDL 2.0 window: %p\n", SDL12COMPAT_GetWindow()); -#endif } + + { + typedef SDL_Window * SDLCALL (*fnSDL12COMPAT_GetWindow)(void); + fnSDL12COMPAT_GetWindow pfnSDL12COMPAT_GetWindow = (fnSDL12COMPAT_GetWindow) SDL_GL_GetProcAddress("SDL12COMPAT_GetWindow"); + printf("SDL12COMPAT_GetWindow address is %p%s\n", pfnSDL12COMPAT_GetWindow, pfnSDL12COMPAT_GetWindow ? "" : " (probably using classic SDL 1.2)"); + if (pfnSDL12COMPAT_GetWindow != NULL) { + printf("SDL 2.0 window: %p\n", pfnSDL12COMPAT_GetWindow()); + } + } + SDL_EventState(SDL_SYSWMEVENT, SDL_ENABLE); #endif From 92fe60a3cecce1513e146944306afae3d8e1db76 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Mon, 10 Oct 2022 21:04:50 +0300 Subject: [PATCH 389/606] testwm.c: fix MSVC build. --- test/testwm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/testwm.c b/test/testwm.c index 16f29bfa5..233ed51fe 100644 --- a/test/testwm.c +++ b/test/testwm.c @@ -460,7 +460,7 @@ int main(int argc, char *argv[]) } { - typedef SDL_Window * SDLCALL (*fnSDL12COMPAT_GetWindow)(void); + typedef SDL_Window* (SDLCALL *fnSDL12COMPAT_GetWindow)(void); fnSDL12COMPAT_GetWindow pfnSDL12COMPAT_GetWindow = (fnSDL12COMPAT_GetWindow) SDL_GL_GetProcAddress("SDL12COMPAT_GetWindow"); printf("SDL12COMPAT_GetWindow address is %p%s\n", pfnSDL12COMPAT_GetWindow, pfnSDL12COMPAT_GetWindow ? "" : " (probably using classic SDL 1.2)"); if (pfnSDL12COMPAT_GetWindow != NULL) { From 63e4393d89482a87bfc91f849c6f32584cc7b21d Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 10 Oct 2022 22:08:18 -0400 Subject: [PATCH 390/606] syswm: Added a quirk to disable SysWM interfaces. And hooked up "fillets" to it. Reference Issue #234. --- README.md | 12 ++++++++++++ src/SDL12_compat.c | 7 +++++++ 2 files changed, 19 insertions(+) diff --git a/README.md b/README.md index 0bab46856..434db4069 100644 --- a/README.md +++ b/README.md @@ -258,6 +258,18 @@ The available options are: completely ignored. The thread that called `SDL_SetVideoMode()` is treated as the main thread. +- SDL12COMPAT_ALLOW_SYSWM: (checked during SDL_Init) + Enabled by default. + If disabled, SDL_SYSWMEVENT events will not be delivered to the app, and + SDL_GetWMInfo() will fail; this is useful if you have a program that + tries to access X11 directly through SDL's interfaces, but can survive + without it, becoming compatible with, for example, Wayland, or perhaps + just avoiding a bug in target-specific code. Note that sdl12-compat already + disallows SysWM things unless SDL2 is using its "windows" or "x11" video + backends, because SDL 1.2 didn't have wide support for its SysWM APIs + outside of Windows and X11 anyhow. + + # Compatibility issues with OpenGL scaling The OpenGL scaling feature of sdl12-compat allows applications which wish to diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index a49b1f9b1..b0fb649a4 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1207,6 +1207,9 @@ static QuirkEntryType quirks[] = { {"tucnak", "SDL_RENDER_DRIVER", "software"}, {"tucnak", "SDL_FRAMEBUFFER_ACCELERATION", "false"}, + /* looks for X11 display and does unnecessary X11 things. Causes problems with SDL2/x11. */ + {"fillets", "SDL12COMPAT_ALLOW_SYSWM", "0"}, + /* The 32-bit Steam build only of Multiwinia Quits but doesn't re-Init */ {"multiwinia.bin.x86", "SDL12COMPAT_NO_QUIT_VIDEO", "1"} #else @@ -2254,6 +2257,10 @@ Init12Video(void) SupportSysWM = SDL_FALSE; #endif + if (!SDL12Compat_GetHintBoolean("SDL12COMPAT_ALLOW_SYSWM", SDL_TRUE)) { + SupportSysWM = SDL_FALSE; + } + SDL_EnableKeyRepeat(0, 0); SDL20_DelEventWatch(EventFilter20to12, NULL); From f763fc75599a1cf2ae1d7bfb82bf093ce6b44f5e Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 14 Oct 2022 01:21:25 -0400 Subject: [PATCH 391/606] events: Key repeat waits the delay PLUS one interval at start. In 1.2, this just sets a flag when the delay is done and restarts the counter for the first interval, but doesn't send a repeat keydown event at this point. To simplify, we just set the initial wait to be the delay plus the interval instead of just the delay. Fixes #251. --- src/SDL12_compat.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index b0fb649a4..468322693 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -4306,7 +4306,8 @@ static int FlushPendingKeydownEvent(Uint32 unicode) if (KeyRepeatDelay) { SDL20_memcpy(&KeyRepeatEvent, &PendingKeydownEvent, sizeof (SDL12_Event)); - KeyRepeatNextTicks = SDL20_GetTicks() + KeyRepeatDelay; + /* SDL 1.2 waits for the delay, and then a full interval past that before the first repeat is reported. */ + KeyRepeatNextTicks = SDL20_GetTicks() + KeyRepeatDelay + KeyRepeatInterval; } /* Reset the event. */ From 35488c6894cb55ae4019392022c418f54dc3eb42 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 14 Oct 2022 13:35:50 -0400 Subject: [PATCH 392/606] Revert "video: Don't ever simulate a hardware palette." This reverts commit 9da8808c03e80a228ee66a714091249f331ebcd7. Fixes #238. Fixes #244. Fixes #246. --- src/SDL12_compat.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 468322693..d502c00d1 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -954,6 +954,7 @@ static SDL_Renderer *VideoRenderer20 = NULL; static SDL_mutex *VideoRendererLock = NULL; static SDL_Texture *VideoTexture20 = NULL; static SDL12_Surface *VideoSurface12 = NULL; +static SDL_Palette *VideoPhysicalPalette20 = NULL; static Uint32 VideoSurfacePresentTicks = 0; static Uint32 VideoSurfaceLastPresentTicks = 0; static SDL_Surface *VideoConvertSurface20 = NULL; @@ -5338,6 +5339,10 @@ EndVidModeCreate(void) SDL20_DestroyWindow(VideoWindow20); VideoWindow20 = NULL; } + if (VideoPhysicalPalette20) { + SDL20_FreePalette(VideoPhysicalPalette20); + VideoPhysicalPalette20 = NULL; + } if (VideoSurface12) { SDL20_free(VideoSurface12->pixels); VideoSurface12->pixels = NULL; @@ -6121,6 +6126,13 @@ SetVideoModeImpl(int width, int height, int bpp, Uint32 flags12) { const int x = (i & 0x3) | ((i & 0x3) << 2); color->b = x | x << 4; } color->a = 255; } + if (!VideoPhysicalPalette20) { + VideoPhysicalPalette20 = SDL20_AllocPalette(256); + if (!VideoPhysicalPalette20) { + return EndVidModeCreate(); + } + } + SDL20_SetPaletteColors(VideoPhysicalPalette20, VideoSurface12->format->palette->colors, 0, 256); } } @@ -6669,6 +6681,7 @@ SDL_UpdateRects(SDL12_Surface *surface12, int numrects, SDL12_Rect *rects12) * don't handle it correctly, so we have to work around it. */ if (surface12 == VideoSurface12) { const SDL_bool upload_later = (!ThisIsSetVideoModeThread && !AllowThreadedDraws) ? SDL_TRUE : SDL_FALSE; + SDL_Palette *logicalPal = surface12->surface20->format->palette; const int pixsize = surface12->format->BytesPerPixel; const int srcpitch = surface12->pitch; SDL_bool whole_screen = SDL_FALSE; @@ -6698,6 +6711,7 @@ SDL_UpdateRects(SDL12_Surface *surface12, int numrects, SDL12_Rect *rects12) dstrect20.x = dstrect20.y = 0; dstrect20.w = rect20.w; dstrect20.h = rect20.h; + surface12->surface20->format->palette = VideoPhysicalPalette20; VideoConvertSurface20->pixels = pixels; VideoConvertSurface20->pitch = pitch; VideoConvertSurface20->w = rect20.w; @@ -6718,6 +6732,7 @@ SDL_UpdateRects(SDL12_Surface *surface12, int numrects, SDL12_Rect *rects12) } if (VideoConvertSurface20) { /* reset some state we messed with */ + surface12->surface20->format->palette = logicalPal; VideoConvertSurface20->pixels = NULL; VideoConvertSurface20->pitch = 0; VideoConvertSurface20->w = VideoSurface12->w; @@ -7114,11 +7129,21 @@ SDL_SetPalette(SDL12_Surface *surface12, int flags, const SDL_Color *colors, } } + if ((flags & SDL12_PHYSPAL) && (surface12 == VideoSurface12) && VideoPhysicalPalette20) { + if (SDL20_SetPaletteColors(VideoPhysicalPalette20, opaquecolors, firstcolor, ncolors) < 0) { + retval = -1; + } + } + SDL20_free(opaquecolors); /* in case this pointer changed... */ palette12->colors = palette20->colors; + if ((surface12 == VideoSurface12) && (flags & SDL12_PHYSPAL)) { + SDL_UpdateRect(surface12, 0, 0, 0, 0); /* force screen to reblit with new palette. */ + } + return retval; } From 2a96bb35d7562f75c710e5824a49eb14c13c1bac Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sun, 16 Oct 2022 07:49:36 -0400 Subject: [PATCH 393/606] quirks: Force X11 on Linux if certain symbols are in the process. So if we see the process references GLEW or Nvidia Cg, we assume the app will fail if it can't talk to glX. This automates the process in many cases instead of having to list these specific titles in the quirks table. This patch in its initial form, and the idea, are from @smvc (thanks!). Fixes #249. Fixes #252. Fixes #258. Fixes #262. Fixes #263. --- src/SDL12_compat.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index d502c00d1..cb97408e5 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1189,11 +1189,9 @@ static QuirkEntryType quirks[] = { #if defined(__unix__) /* Awesomenauts uses Cg, and does weird things with the GL context. */ {"Awesomenauts.bin.x86", "SDL12COMPAT_OPENGL_SCALING", "0"}, - {"Awesomenauts.bin.x86", "SDL_VIDEODRIVER", "x11"}, {"Awesomenauts.bin.x86", "SDL12COMPAT_FORCE_GL_SWAPBUFFER_CONTEXT", "1"}, /* Braid uses Cg, which uses glXGetProcAddress(). */ - {"braid", "SDL_VIDEODRIVER", "x11"}, {"braid", "SDL12COMPAT_OPENGL_SCALING", "0"}, /* GOG's DOSBox builds have architecture-specific filenames. */ @@ -1329,6 +1327,30 @@ SDL12Compat_ApplyQuirks(void) } } } + + #ifdef __linux__ + { + void *global_symbols = dlopen(NULL, RTLD_LOCAL|RTLD_NOW); + SDL_bool force_x11 = SDL_FALSE; + + /* Use linked libraries to detect what quirks we are likely to need */ + if (global_symbols != NULL) { + /* GLEW (e.g. Frogatto, SLUDGE) */ + if (dlsym(global_symbols, "glxewInit") != NULL) { force_x11 = SDL_TRUE; } + /* NVIDIA Cg (e.g. Awesomenauts, Braid) */ + else if (dlsym(global_symbols, "cgGLEnableProgramProfiles") != NULL) { force_x11 = SDL_TRUE; } + } + + dlclose(global_symbols); + + if (force_x11) { + SDL20_Log("sdl12-compat: We are forcing this app to use X11, because it probably"); + SDL20_Log("sdl12-compat: talks to an X server directly, outside of SDL. If possible,"); + SDL20_Log("sdl12-compat: this app should be fixed, to be compatible with Wayland, etc."); + SDL20_setenv("SDL_VIDEODRIVER", "x11", 1); + } + } + #endif } static int From 0fb5c56eaa5c74044c0830909627935718dd02f2 Mon Sep 17 00:00:00 2001 From: David Gow Date: Mon, 17 Oct 2022 17:35:14 +0800 Subject: [PATCH 394/606] quirks: Fixes for symbol-based quirks to force X11 Make some changes to how the automatic quirks for apps which link against gl[x]ew and Cg functions work. In particular: - They can be overridden by a user-set SDL_VIDEODRIVER env variable. - They only print warnings if debug logging (SDL12COMPAT_DEBUG_LOGGING=1) is enabled, to match the other quirks. - The messages are no-longer wrapped. Fixes: 2a96bb35d756 ("quirks: Force X11 on Linux if certain symbols are in the process.") --- src/SDL12_compat.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index cb97408e5..2451e7a5d 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1307,6 +1307,7 @@ static void SDL12Compat_ApplyQuirks(void) { const char *exe_name = SDL12Compat_GetExeName(); + const char *videodriver_env = SDL20_getenv("SDL_VIDEODRIVER"); int i; if (*exe_name == '\0') { @@ -1329,6 +1330,7 @@ SDL12Compat_ApplyQuirks(void) } #ifdef __linux__ + if (!videodriver_env || SDL20_strcmp(videodriver_env, "x11")) { void *global_symbols = dlopen(NULL, RTLD_LOCAL|RTLD_NOW); SDL_bool force_x11 = SDL_FALSE; @@ -1344,10 +1346,14 @@ SDL12Compat_ApplyQuirks(void) dlclose(global_symbols); if (force_x11) { - SDL20_Log("sdl12-compat: We are forcing this app to use X11, because it probably"); - SDL20_Log("sdl12-compat: talks to an X server directly, outside of SDL. If possible,"); - SDL20_Log("sdl12-compat: this app should be fixed, to be compatible with Wayland, etc."); - SDL20_setenv("SDL_VIDEODRIVER", "x11", 1); + if (!videodriver_env) { + if (WantDebugLogging) { + SDL20_Log("Forcing this app to use X11, because it probably talks to an X server directly, outside of SDL. If possible, this app should be fixed, to be compatible with Wayland, etc."); + } + SDL20_setenv("SDL_VIDEODRIVER", "x11", 1); + } else if (videodriver_env && WantDebugLogging) { + SDL20_Log("This app looks like it requires X11, but the SDL_VIDEODRIVER environment variable is set to \"%s\". If you have issues, try setting SDL_VIDEODRIVER=x11", videodriver_env); + } } } #endif From 6c7422aac7207f68dcbd42584de4c4617b0edba7 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 17 Oct 2022 08:44:52 -0400 Subject: [PATCH 395/606] quirks: Better X11 test. - Do the test before loading SDL2, in case SDL2 is explicitly linked to Xlib. - Reformatted code. - Only dlclose() if dlopen() succeeded. - Report that we're forcing X11 on a single line of text to stderr. Reference Issue #249. --- src/SDL12_compat.c | 51 +++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index cb97408e5..457da8210 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1304,11 +1304,18 @@ SDL12Compat_GetHintFloat(const char *name, float default_value) } static void -SDL12Compat_ApplyQuirks(void) +SDL12Compat_ApplyQuirks(SDL_bool force_x11) { const char *exe_name = SDL12Compat_GetExeName(); int i; + #ifdef __linux__ + if (force_x11) { + SDL20_Log("sdl12-compat: We are forcing this app to use X11, because it probably talks to an X server directly, outside of SDL. If possible, this app should be fixed, to be compatible with Wayland, etc."); + SDL20_setenv("SDL_VIDEODRIVER", "x11", 1); + } + #endif + if (*exe_name == '\0') { return; } @@ -1327,30 +1334,6 @@ SDL12Compat_ApplyQuirks(void) } } } - - #ifdef __linux__ - { - void *global_symbols = dlopen(NULL, RTLD_LOCAL|RTLD_NOW); - SDL_bool force_x11 = SDL_FALSE; - - /* Use linked libraries to detect what quirks we are likely to need */ - if (global_symbols != NULL) { - /* GLEW (e.g. Frogatto, SLUDGE) */ - if (dlsym(global_symbols, "glxewInit") != NULL) { force_x11 = SDL_TRUE; } - /* NVIDIA Cg (e.g. Awesomenauts, Braid) */ - else if (dlsym(global_symbols, "cgGLEnableProgramProfiles") != NULL) { force_x11 = SDL_TRUE; } - } - - dlclose(global_symbols); - - if (force_x11) { - SDL20_Log("sdl12-compat: We are forcing this app to use X11, because it probably"); - SDL20_Log("sdl12-compat: talks to an X server directly, outside of SDL. If possible,"); - SDL20_Log("sdl12-compat: this app should be fixed, to be compatible with Wayland, etc."); - SDL20_setenv("SDL_VIDEODRIVER", "x11", 1); - } - } - #endif } static int @@ -1358,6 +1341,22 @@ LoadSDL20(void) { int okay = 1; if (!Loaded_SDL20) { + SDL_bool force_x11 = SDL_FALSE; + + #ifdef __linux__ + void *global_symbols = dlopen(NULL, RTLD_LOCAL|RTLD_NOW); + + /* Use linked libraries to detect what quirks we are likely to need */ + if (global_symbols != NULL) { + if (dlsym(global_symbols, "glxewInit") != NULL) { /* GLEW (e.g. Frogatto, SLUDGE) */ + force_x11 = SDL_TRUE; + } else if (dlsym(global_symbols, "cgGLEnableProgramProfiles") != NULL) { /* NVIDIA Cg (e.g. Awesomenauts, Braid) */ + force_x11 = SDL_TRUE; + } + dlclose(global_symbols); + } + #endif + okay = LoadSDL20Library(); if (!okay) { strcpy_fn(loaderror, "Failed loading SDL2 library."); @@ -1380,7 +1379,7 @@ LoadSDL20(void) SDL20_Log("sdl12-compat 1.2.%d, talking to SDL2 %d.%d.%d", SDL12_COMPAT_VERSION, v.major, v.minor, v.patch); #endif } - SDL12Compat_ApplyQuirks(); /* Apply and maybe print a list of any enabled quirks. */ + SDL12Compat_ApplyQuirks(force_x11); /* Apply and maybe print a list of any enabled quirks. */ } } if (!okay) { From abb33cddffb7e7551acab724922225d88f13474f Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 17 Oct 2022 08:44:52 -0400 Subject: [PATCH 396/606] quirks: Better X11 test. - Do the test before loading SDL2, in case SDL2 is explicitly linked to Xlib. - Reformatted code. - Only dlclose() if dlopen() succeeded. - Report that we're forcing X11 on a single line of text to stderr. Reference Issue #249. --- src/SDL12_compat.c | 64 ++++++++++++++++++++++++---------------------- 1 file changed, 33 insertions(+), 31 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 2451e7a5d..9db296e49 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1304,12 +1304,27 @@ SDL12Compat_GetHintFloat(const char *name, float default_value) } static void -SDL12Compat_ApplyQuirks(void) +SDL12Compat_ApplyQuirks(SDL_bool force_x11) { const char *exe_name = SDL12Compat_GetExeName(); - const char *videodriver_env = SDL20_getenv("SDL_VIDEODRIVER"); int i; + #ifdef __linux__ + if (force_x11) { + const char *videodriver_env = SDL20_getenv("SDL_VIDEODRIVER"); + if (videodriver_env && (SDL20_strcmp(videodriver_env, "x11") != 0)) { + if (WantDebugLogging) { + SDL20_Log("This app looks like it requires X11, but the SDL_VIDEODRIVER environment variable is set to \"%s\". If you have issues, try setting SDL_VIDEODRIVER=x11", videodriver_env); + } + } else { + if (WantDebugLogging) { + SDL20_Log("sdl12-compat: We are forcing this app to use X11, because it probably talks to an X server directly, outside of SDL. If possible, this app should be fixed, to be compatible with Wayland, etc."); + } + SDL20_setenv("SDL_VIDEODRIVER", "x11", 1); + } + } + #endif + if (*exe_name == '\0') { return; } @@ -1328,42 +1343,29 @@ SDL12Compat_ApplyQuirks(void) } } } +} - #ifdef __linux__ - if (!videodriver_env || SDL20_strcmp(videodriver_env, "x11")) - { - void *global_symbols = dlopen(NULL, RTLD_LOCAL|RTLD_NOW); +static int +LoadSDL20(void) +{ + int okay = 1; + if (!Loaded_SDL20) { SDL_bool force_x11 = SDL_FALSE; + #ifdef __linux__ + void *global_symbols = dlopen(NULL, RTLD_LOCAL|RTLD_NOW); + /* Use linked libraries to detect what quirks we are likely to need */ if (global_symbols != NULL) { - /* GLEW (e.g. Frogatto, SLUDGE) */ - if (dlsym(global_symbols, "glxewInit") != NULL) { force_x11 = SDL_TRUE; } - /* NVIDIA Cg (e.g. Awesomenauts, Braid) */ - else if (dlsym(global_symbols, "cgGLEnableProgramProfiles") != NULL) { force_x11 = SDL_TRUE; } - } - - dlclose(global_symbols); - - if (force_x11) { - if (!videodriver_env) { - if (WantDebugLogging) { - SDL20_Log("Forcing this app to use X11, because it probably talks to an X server directly, outside of SDL. If possible, this app should be fixed, to be compatible with Wayland, etc."); - } - SDL20_setenv("SDL_VIDEODRIVER", "x11", 1); - } else if (videodriver_env && WantDebugLogging) { - SDL20_Log("This app looks like it requires X11, but the SDL_VIDEODRIVER environment variable is set to \"%s\". If you have issues, try setting SDL_VIDEODRIVER=x11", videodriver_env); + if (dlsym(global_symbols, "glxewInit") != NULL) { /* GLEW (e.g. Frogatto, SLUDGE) */ + force_x11 = SDL_TRUE; + } else if (dlsym(global_symbols, "cgGLEnableProgramProfiles") != NULL) { /* NVIDIA Cg (e.g. Awesomenauts, Braid) */ + force_x11 = SDL_TRUE; } + dlclose(global_symbols); } - } - #endif -} + #endif -static int -LoadSDL20(void) -{ - int okay = 1; - if (!Loaded_SDL20) { okay = LoadSDL20Library(); if (!okay) { strcpy_fn(loaderror, "Failed loading SDL2 library."); @@ -1386,7 +1388,7 @@ LoadSDL20(void) SDL20_Log("sdl12-compat 1.2.%d, talking to SDL2 %d.%d.%d", SDL12_COMPAT_VERSION, v.major, v.minor, v.patch); #endif } - SDL12Compat_ApplyQuirks(); /* Apply and maybe print a list of any enabled quirks. */ + SDL12Compat_ApplyQuirks(force_x11); /* Apply and maybe print a list of any enabled quirks. */ } } if (!okay) { From c549425b8d8e4d67e5412ffe84ab47d3aee1bcc3 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 19 Oct 2022 13:17:38 -0400 Subject: [PATCH 397/606] video: SDL_UpperBlit should reject surfaces with NULL pixels. Fixes #264. --- src/SDL12_compat.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 9db296e49..8dfdf4f9b 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -6328,6 +6328,8 @@ SDL_UpperBlit(SDL12_Surface *src12, SDL12_Rect *srcrect12, SDL12_Surface *dst12, if ((src12 == NULL) || (dst12 == NULL)) { return SDL20_SetError("SDL_UpperBlit: passed a NULL surface"); + } else if ((src12->pixels == NULL) || (dst12->pixels == NULL)) { + return SDL20_SetError("SDL_UpperBlit: passed a surface with NULL pixels"); } else if (SaveDestAlpha(src12, dst12, dstrect12, &dstalpha) < 0) { return -1; } From b1f9d4a206c74c54bb48bbfa0402c977147a3bc7 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 19 Oct 2022 13:31:24 -0400 Subject: [PATCH 398/606] quirks: Disable GL scaling for scorched3d (and its client, scorched3dc). Fixes #261. --- src/SDL12_compat.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 8dfdf4f9b..79ec24176 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1209,6 +1209,10 @@ static QuirkEntryType quirks[] = { /* looks for X11 display and does unnecessary X11 things. Causes problems with SDL2/x11. */ {"fillets", "SDL12COMPAT_ALLOW_SYSWM", "0"}, + /* doesn't render with GL scaling enabled */ + {"scorched3d", "SDL12COMPAT_OPENGL_SCALING", "0"}, + {"scorched3dc", "SDL12COMPAT_OPENGL_SCALING", "0"}, + /* The 32-bit Steam build only of Multiwinia Quits but doesn't re-Init */ {"multiwinia.bin.x86", "SDL12COMPAT_NO_QUIT_VIDEO", "1"} #else From e86d0247d48d490f61bf94489ed3882edc6f8263 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 19 Oct 2022 15:50:41 -0400 Subject: [PATCH 399/606] video: If trying to create a < 8 bit surface, force it to 8 bits. This gets around a specific game (rockdodger) that creates a 2-bit surface just to convert it to display format. This is likely to confuse any game that wants to directly manipulate pixels and isn't getting the surface they expected, but until now those games were simply failing here, so we'll revisit with a more-complex solution when the need arises. Fixes #260. --- src/SDL12_compat.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 79ec24176..1c1b0e150 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -4984,6 +4984,13 @@ SDL_CreateRGBSurface(Uint32 flags12, int width, int height, int depth, Uint32 Rm return NULL; } + /* !!! FIXME: this isn't strictly correct, but SDL2 doesn't support + !!! FIXME: surfaces smaller than 8 bits, and this lets at + !!! FIXME: least one game function correctly. */ + if (depth < 8) { + depth = 8; + } + if (depth == 8) { /* don't pass masks to SDL2 for 8-bit surfaces, it'll cause problems. */ surface20 = SDL20_CreateRGBSurface(0, width, height, depth, 0, 0, 0, 0); } else { From eaeaf932ba7439ee9a75c1729ff8bd4b446e1b1e Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 19 Oct 2022 18:54:05 -0400 Subject: [PATCH 400/606] video: Add a fallback case for creating 16-bit surfaces with bogus masks. Fixes #257. --- src/SDL12_compat.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 1c1b0e150..fb134a10d 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -5003,12 +5003,19 @@ SDL_CreateRGBSurface(Uint32 flags12, int width, int height, int depth, Uint32 Rm a generic blitter that just copied data blindly. SDL2 wants more strict pixel formats, so try to detect this case and try again with a standard format. */ - if ((surface20 == NULL) && (depth >= 24) && (SDL20_MasksToPixelFormatEnum(depth, Rmask, Gmask, Bmask, Amask) == SDL_PIXELFORMAT_UNKNOWN)) { + if ((surface20 == NULL) && (depth >= 16) && (SDL20_MasksToPixelFormatEnum(depth, Rmask, Gmask, Bmask, Amask) == SDL_PIXELFORMAT_UNKNOWN)) { /* I have no illusions this is correct, it just works for the known problem cases so far. */ - Rmask = SDL_SwapLE32(0x000000FF); - Gmask = SDL_SwapLE32(0x0000FF00); - Bmask = SDL_SwapLE32(0x00FF0000); - Amask = SDL_SwapLE32(Amask ? 0xFF000000 : 0x00000000); + if (depth == 16) { + Rmask = SDL_SwapLE32(0x0000F800); + Gmask = SDL_SwapLE32(0x000007E0); + Bmask = SDL_SwapLE32(0x0000001F); + Amask = 0; + } else { + Rmask = SDL_SwapLE32(0x000000FF); + Gmask = SDL_SwapLE32(0x0000FF00); + Bmask = SDL_SwapLE32(0x00FF0000); + Amask = SDL_SwapLE32(Amask ? 0xFF000000 : 0x00000000); + } surface20 = SDL20_CreateRGBSurface(0, width, height, depth, Rmask, Gmask, Bmask, Amask); } From 92d5c352d555ec578ec4c291cc7016e3c2132b26 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 19 Oct 2022 19:36:57 -0400 Subject: [PATCH 401/606] video: Add debug logging for less-than-8-bit-surface hack. Reference Issue #260. --- src/SDL12_compat.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index fb134a10d..5b964dae9 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -4988,6 +4988,9 @@ SDL_CreateRGBSurface(Uint32 flags12, int width, int height, int depth, Uint32 Rm !!! FIXME: surfaces smaller than 8 bits, and this lets at !!! FIXME: least one game function correctly. */ if (depth < 8) { + if (WantDebugLogging) { + SDL20_Log("This app is creating an %d-bit SDL_Surface, but we are bumping it to 8-bits. If you see rendering issues, please report them!"); + } depth = 8; } From 0459dbe3b630d437d11671c81f3fed69016c8743 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 19 Oct 2022 22:18:46 -0400 Subject: [PATCH 402/606] video: Don't lose colorkey state on converted surfaces. Fixes #250. --- src/SDL12_compat.c | 41 +++++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 5b964dae9..4173b13dc 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -6455,6 +6455,24 @@ SDL_UnlockSurface(SDL12_Surface *surface12) surface12->pitch = surface12->surface20->pitch; } +DECLSPEC12 int SDLCALL +SDL_SetColorKey(SDL12_Surface *surface12, Uint32 flag12, Uint32 key) +{ + const SDL_bool addkey = (flag12 & SDL12_SRCCOLORKEY) ? SDL_TRUE : SDL_FALSE; + const int retval = SDL20_SetColorKey(surface12->surface20, addkey, key); + if (SDL20_GetColorKey(surface12->surface20, &surface12->format->colorkey) < 0) { + surface12->format->colorkey = 0; + } + + if (addkey) { + surface12->flags |= SDL12_SRCCOLORKEY; + } else { + surface12->flags &= ~SDL12_SRCCOLORKEY; + } + + return retval; +} + DECLSPEC12 SDL12_Surface * SDLCALL SDL_ConvertSurface(SDL12_Surface *src12, const SDL12_PixelFormat *format12, Uint32 flags12) { @@ -6477,6 +6495,11 @@ SDL_ConvertSurface(SDL12_Surface *src12, const SDL12_PixelFormat *format12, Uint SDL20_SetSurfaceBlendMode(surface20, SDL_BLENDMODE_BLEND); retval->flags |= SDL12_SRCALPHA; } + if (flags12 & SDL12_SRCCOLORKEY) { + Uint8 r, g, b, a; + SDL20_GetRGBA(src12->format->colorkey, src12->surface20->format, &r, &g, &b, &a); + SDL_SetColorKey(retval, SDL12_SRCCOLORKEY, SDL20_MapRGBA(retval->surface20->format, r, g, b, a)); + } } } return retval; @@ -7116,24 +7139,6 @@ SDL_GetAppState(void) return state12; } -DECLSPEC12 int SDLCALL -SDL_SetColorKey(SDL12_Surface *surface12, Uint32 flag12, Uint32 key) -{ - const SDL_bool addkey = (flag12 & SDL12_SRCCOLORKEY) ? SDL_TRUE : SDL_FALSE; - const int retval = SDL20_SetColorKey(surface12->surface20, addkey, key); - if (SDL20_GetColorKey(surface12->surface20, &surface12->format->colorkey) < 0) { - surface12->format->colorkey = 0; - } - - if (addkey) { - surface12->flags |= SDL12_SRCCOLORKEY; - } else { - surface12->flags &= ~SDL12_SRCCOLORKEY; - } - - return retval; -} - DECLSPEC12 int SDLCALL SDL_SetPalette(SDL12_Surface *surface12, int flags, const SDL_Color *colors, int firstcolor, int ncolors) From 0668c11486d33eea06beae8782777001dd17459d Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 20 Oct 2022 23:48:27 -0400 Subject: [PATCH 403/606] video: Fix apps that UpdateRect and never PumpEvents. An app that _only_ calls SDL_UpdateRects (perhaps to draw just a piece of animation that doesn't cover the screen but while not accepting user input) will now check inside SDL_UpdateRects itself to decide if enough time has gone by to warrant a present. Also, if SDL_Delay is called and a present is pending at all, just do it, as a signal from the app that the frame is complete. This catches things that update a rectangle and then delay for the user to view it. Fixes #253. --- src/SDL12_compat.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 4173b13dc..26b5caaef 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -6821,7 +6821,11 @@ SDL_UpdateRects(SDL12_Surface *surface12, int numrects, SDL12_Rect *rects12) } else if (whole_screen) { PresentScreen(); /* flip it now. */ } else { - VideoSurfacePresentTicks = VideoSurfaceLastPresentTicks + GetDesiredMillisecondsPerFrame(); /* flip it later. */ + if (!VideoSurfacePresentTicks) { + VideoSurfacePresentTicks = VideoSurfaceLastPresentTicks + GetDesiredMillisecondsPerFrame(); /* flip it later. */ + } else if (SDL_TICKS_PASSED(SDL20_GetTicks(), VideoSurfacePresentTicks)) { + PresentScreen(); + } } if (renderer) { @@ -7828,9 +7832,14 @@ SDL_Delay(Uint32 ticks) { /* In case there's a loading screen from a background thread and the main thread is waiting... */ const SDL_bool ThisIsSetVideoModeThread = (SDL20_ThreadID() == SetVideoModeThread) ? SDL_TRUE : SDL_FALSE; - if (ThisIsSetVideoModeThread && VideoSurfaceUpdatedInBackgroundThread) { - SDL_Flip(VideoSurface12); /* this will update the texture and present. */ + if (ThisIsSetVideoModeThread) { + if (VideoSurfaceUpdatedInBackgroundThread) { + SDL_Flip(VideoSurface12); /* this will update the texture and present. */ + } else if (VideoSurfacePresentTicks) { + PresentScreen(); + } } + SDL20_Delay(ticks); } From 67f8b3a85b782eefb4db90f34d5b0742ef2cb5fc Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sat, 22 Oct 2022 20:55:00 +0300 Subject: [PATCH 404/606] os2: make sure we be able to load SDL2.dll from LIBPATH See http://www.edm2.com/index.php/DosLoadModule#Gotchas --- src/SDL12_compat.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 26b5caaef..1077c92af 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1057,6 +1057,7 @@ static char loaderror[256]; #include #define DIRSEP "\\" #define SDL20_LIBNAME "SDL2.dll" + #define SDL20_LIBNAME2 "SDL2" /* if loading from LIBPATH */ #define SDL20_REQUIRED_VER SDL_VERSIONNUM(2,0,7) #define strcpy_fn strcpy #define sprintf_fn sprintf @@ -1064,7 +1065,9 @@ static char loaderror[256]; static SDL_bool LoadSDL20Library(void) { char err[256]; if (DosLoadModule(err, sizeof(err), SDL20_LIBNAME, &Loaded_SDL20) != 0) { - return SDL_FALSE; + if (DosLoadModule(err, sizeof(err), SDL20_LIBNAME2, &Loaded_SDL20) != 0) { + return SDL_FALSE; + } } return SDL_TRUE; } From 38132e2e828bf6a8865c69351632395dbe0f02ec Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Mon, 24 Oct 2022 14:29:41 +0100 Subject: [PATCH 405/606] quirks: Force X11 if plib (specifically libplibssg) is detected crrcsim, a model aeroplane simulator, is linked to both SDL 1.2 and plib. I'm not entirely sure why, since plib seems to be an (unmaintained) alternative to SDL that did many of the same things. Because plib has a C++ ABI but dlsym() works with C-level ABI, we need to use a C++ mangled name for the symbol we look for. Resolves: https://github.com/libsdl-org/sdl12-compat/issues/252 Signed-off-by: Simon McVittie --- src/SDL12_compat.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 1077c92af..612d190fa 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1368,6 +1368,8 @@ LoadSDL20(void) force_x11 = SDL_TRUE; } else if (dlsym(global_symbols, "cgGLEnableProgramProfiles") != NULL) { /* NVIDIA Cg (e.g. Awesomenauts, Braid) */ force_x11 = SDL_TRUE; + } else if (dlsym(global_symbols, "_Z7ssgInitv") != NULL) { /* ::ssgInit(void) in plib (e.g. crrcsim) */ + force_x11 = SDL_TRUE; } dlclose(global_symbols); } From 219c3585f456cbd9eb9245835923861fcddb6eaf Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Mon, 24 Oct 2022 14:51:10 +0100 Subject: [PATCH 406/606] Fix missing format string argument in low-bit-depth workaround Signed-off-by: Simon McVittie --- src/SDL12_compat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 612d190fa..eae326ca6 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -4994,7 +4994,7 @@ SDL_CreateRGBSurface(Uint32 flags12, int width, int height, int depth, Uint32 Rm !!! FIXME: least one game function correctly. */ if (depth < 8) { if (WantDebugLogging) { - SDL20_Log("This app is creating an %d-bit SDL_Surface, but we are bumping it to 8-bits. If you see rendering issues, please report them!"); + SDL20_Log("This app is creating an %d-bit SDL_Surface, but we are bumping it to 8-bits. If you see rendering issues, please report them!", depth); } depth = 8; } From 61e247dfd57b8aebdc3078f9c1657079b7e66721 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 24 Oct 2022 10:53:44 -0400 Subject: [PATCH 407/606] SaveDestAlpha: clamp dest rectangle correctly. SDL blits only care about the destination x and y, ignoring the w and h, and then we need to clamp on top of that anyhow, in case the x and y are out of bounds. Reference Issue #244. --- src/SDL12_compat.c | 73 +++++++++++++++++++++++++--------------------- 1 file changed, 40 insertions(+), 33 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index eae326ca6..70427258a 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -6232,7 +6232,7 @@ SDL_GetVideoSurface(void) } static int -SaveDestAlpha(SDL12_Surface *src12, SDL12_Surface *dst12, const SDL12_Rect *dstrect12, Uint8 **retval) +SaveDestAlpha(SDL12_Surface *src12, SDL12_Surface *dst12, SDL_Rect *dstrect20, Uint8 **retval) { /* The 1.2 docs say this: * RGBA->RGBA: @@ -6245,24 +6245,15 @@ SaveDestAlpha(SDL12_Surface *src12, SDL12_Surface *dst12, const SDL12_Rect *dstr Uint8 *dstalpha = NULL; const SDL_bool save_dstalpha = ((src12->flags & SDL12_SRCALPHA) && dst12->format->Amask && ((src12->format->alpha != 255) || src12->format->Amask)) ? SDL_TRUE : SDL_FALSE; - if (save_dstalpha) { + if (save_dstalpha && (dstrect20->w > 0) && (dstrect20->h > 0)) { const Uint32 amask = dst12->format->Amask; const Uint32 ashift = dst12->format->Ashift; const Uint16 pitch = dst12->pitch; - SDL12_Rect fullrect; Uint8 *dptr; int x, y, w, h; - if (!dstrect12) { - fullrect.x = 0; - fullrect.y = 0; - fullrect.w = dst12->w; - fullrect.h = dst12->h; - dstrect12 = &fullrect; - } - - w = dstrect12->w; - h = dstrect12->h; + w = dstrect20->w; + h = dstrect20->h; dstalpha = (Uint8 *) SDL20_malloc(w * h); if (!dstalpha) { @@ -6273,7 +6264,7 @@ SaveDestAlpha(SDL12_Surface *src12, SDL12_Surface *dst12, const SDL12_Rect *dstr if (dst12->format->BytesPerPixel == 2) { const Uint16 *sptr = (const Uint16 *) dst12->pixels; - sptr += ((dst12->pitch / 2) * dstrect12->y) + dstrect12->x; + sptr += ((dst12->pitch / 2) * dstrect20->y) + dstrect20->x; for (y = 0; y < h; y++) { for (x = 0; x < w; x++) { *(dptr++) = (Uint8) ((sptr[x] & amask) >> ashift); @@ -6282,7 +6273,7 @@ SaveDestAlpha(SDL12_Surface *src12, SDL12_Surface *dst12, const SDL12_Rect *dstr } } else if (dst12->format->BytesPerPixel == 4) { const Uint32 *sptr = (const Uint32 *) dst12->pixels; - sptr += ((dst12->pitch / 4) * dstrect12->y) + dstrect12->x; + sptr += ((dst12->pitch / 4) * dstrect20->y) + dstrect20->x; for (y = 0; y < h; y++) { for (x = 0; x < w; x++) { *(dptr++) = (Uint8) ((sptr[x] & amask) >> ashift); @@ -6299,30 +6290,21 @@ SaveDestAlpha(SDL12_Surface *src12, SDL12_Surface *dst12, const SDL12_Rect *dstr } static void -RestoreDestAlpha(SDL12_Surface *dst12, Uint8 *dstalpha, const SDL12_Rect *dstrect12) +RestoreDestAlpha(SDL12_Surface *dst12, Uint8 *dstalpha, const SDL_Rect *dstrect20) { if (dstalpha) { const Uint8 *sptr = dstalpha; const Uint32 amask = dst12->format->Amask; const Uint32 ashift = dst12->format->Ashift; const Uint16 pitch = dst12->pitch; - SDL12_Rect fullrect; int x, y, w, h; - if (!dstrect12) { - fullrect.x = 0; - fullrect.y = 0; - fullrect.w = dst12->w; - fullrect.h = dst12->h; - dstrect12 = &fullrect; - } - - w = dstrect12->w; - h = dstrect12->h; + w = dstrect20->w; + h = dstrect20->h; if (dst12->format->BytesPerPixel == 2) { Uint16 *dptr = (Uint16 *) dst12->pixels; - dptr += ((dst12->pitch / 2) * dstrect12->y) + dstrect12->x; + dptr += ((dst12->pitch / 2) * dstrect20->y) + dstrect20->x; for (y = 0; y < h; y++) { for (x = 0; x < w; x++) { dptr[x] = (Uint16) ((dptr[x] & ~amask) | ((((Uint16) *(sptr++)) << ashift) & amask)); @@ -6331,7 +6313,7 @@ RestoreDestAlpha(SDL12_Surface *dst12, Uint8 *dstalpha, const SDL12_Rect *dstrec } } else if (dst12->format->BytesPerPixel == 4) { Uint32 *dptr = (Uint32 *) dst12->pixels; - dptr += ((dst12->pitch / 4) * dstrect12->y) + dstrect12->x; + dptr += ((dst12->pitch / 4) * dstrect20->y) + dstrect20->x; for (y = 0; y < h; y++) { for (x = 0; x < w; x++) { dptr[x] = (dptr[x] & ~amask) | ((((Uint32) *(sptr++)) << ashift) & amask); @@ -6345,6 +6327,27 @@ RestoreDestAlpha(SDL12_Surface *dst12, Uint8 *dstalpha, const SDL12_Rect *dstrec } } +static void +PrepBlitDestRect(SDL_Rect *dstrect20, SDL12_Surface *dst12, const SDL12_Rect *dstrect12) +{ + /* dstrect12 w and h is ignored, SDL 1.2 only cares about position. */ + dstrect20->w = dst12->w; + dstrect20->h = dst12->h; + + if (dstrect12) { + SDL_Rect fulldstrect20; + fulldstrect20.x = fulldstrect20.y = 0; + fulldstrect20.w = dst12->w; + fulldstrect20.h = dst12->h; + dstrect20->x = dstrect12->x; + dstrect20->y = dstrect12->y; + SDL20_IntersectRect(&fulldstrect20, dstrect20, dstrect20); + } else { + dstrect20->x = 0; + dstrect20->y = 0; + } +} + DECLSPEC12 int SDLCALL SDL_UpperBlit(SDL12_Surface *src12, SDL12_Rect *srcrect12, SDL12_Surface *dst12, SDL12_Rect *dstrect12) { @@ -6352,11 +6355,13 @@ SDL_UpperBlit(SDL12_Surface *src12, SDL12_Rect *srcrect12, SDL12_Surface *dst12, SDL_Rect srcrect20, dstrect20; int retval; + PrepBlitDestRect(&dstrect20, dst12, dstrect12); + if ((src12 == NULL) || (dst12 == NULL)) { return SDL20_SetError("SDL_UpperBlit: passed a NULL surface"); } else if ((src12->pixels == NULL) || (dst12->pixels == NULL)) { return SDL20_SetError("SDL_UpperBlit: passed a surface with NULL pixels"); - } else if (SaveDestAlpha(src12, dst12, dstrect12, &dstalpha) < 0) { + } else if (SaveDestAlpha(src12, dst12, &dstrect20, &dstalpha) < 0) { return -1; } @@ -6365,7 +6370,7 @@ SDL_UpperBlit(SDL12_Surface *src12, SDL12_Rect *srcrect12, SDL12_Surface *dst12, dst12->surface20, dstrect12 ? Rect12to20(dstrect12, &dstrect20) : NULL); - RestoreDestAlpha(dst12, dstalpha, dstrect12); + RestoreDestAlpha(dst12, dstalpha, &dstrect20); if (dstrect12) { Rect20to12(&dstrect20, dstrect12); @@ -6381,7 +6386,9 @@ SDL_LowerBlit(SDL12_Surface *src12, SDL12_Rect *srcrect12, SDL12_Surface *dst12, SDL_Rect srcrect20, dstrect20; int retval; - if (SaveDestAlpha(src12, dst12, dstrect12, &dstalpha) < 0) { + PrepBlitDestRect(&dstrect20, dst12, dstrect12); + + if (SaveDestAlpha(src12, dst12, &dstrect20, &dstalpha) < 0) { return -1; } @@ -6390,7 +6397,7 @@ SDL_LowerBlit(SDL12_Surface *src12, SDL12_Rect *srcrect12, SDL12_Surface *dst12, dst12->surface20, dstrect12 ? Rect12to20(dstrect12, &dstrect20) : NULL); - RestoreDestAlpha(dst12, dstalpha, dstrect12); + RestoreDestAlpha(dst12, dstalpha, &dstrect20); if (srcrect12) { Rect20to12(&srcrect20, srcrect12); From 43887001c05c64eb23eb5312c0f62e9841618700 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 24 Oct 2022 14:15:56 -0400 Subject: [PATCH 408/606] Bumped version to 1.2.60 for release! --- CMakeLists.txt | 4 ++-- include/SDL/SDL_version.h | 2 +- src/Makefile.darwin | 2 +- src/Makefile.linux | 2 +- src/Makefile.os2 | 2 +- src/Makefile.w32 | 2 +- src/SDL12_compat.c | 2 +- src/version.rc | 8 ++++---- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0ea691415..57c0e9371 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.0.0) project(sdl12_compat - VERSION 1.2.59 + VERSION 1.2.60 LANGUAGES C) option(SDL12TESTS "Enable to build SDL-1.2 test programs" ON) @@ -33,7 +33,7 @@ if(APPLE) # Xcode project file uses 1.0.0, but it's more compatible to use the # higher version. set(DYLIB_COMPAT_VERSION 12.0.0 CACHE STRING "library compatibility version") - set(DYLIB_CURRENT_VERSION 12.59.0 CACHE STRING "library current version") + set(DYLIB_CURRENT_VERSION 12.60.0 CACHE STRING "library current version") include_directories("/opt/X11/include") # hack. if(CMAKE_VERSION VERSION_LESS 3.9) else() diff --git a/include/SDL/SDL_version.h b/include/SDL/SDL_version.h index 15d797fb3..2715320fc 100644 --- a/include/SDL/SDL_version.h +++ b/include/SDL/SDL_version.h @@ -33,7 +33,7 @@ real SDL-1.2 available to you. */ /* We bumped the patchlevel to 50 for sdl12-compat */ #define SDL_MAJOR_VERSION 1 #define SDL_MINOR_VERSION 2 -#define SDL_PATCHLEVEL 59 +#define SDL_PATCHLEVEL 60 typedef struct SDL_version { diff --git a/src/Makefile.darwin b/src/Makefile.darwin index 6e1487864..0edb230f1 100644 --- a/src/Makefile.darwin +++ b/src/Makefile.darwin @@ -18,7 +18,7 @@ CFLAGS = -mmacosx-version-min=10.6 -fPIC -O3 -Wall LDFLAGS = -mmacosx-version-min=10.6 -dynamiclib -Wl,-undefined,error -Wl,-single_module #LDFLAGS+= -Wl,-headerpad_max_install_names LDFLAGS+= -Wl,-install_name,"/usr/local/lib/$(DYLIB)" -LDFLAGS+= -Wl,-compatibility_version,1.0 -Wl,-current_version,12.59 +LDFLAGS+= -Wl,-compatibility_version,1.0 -Wl,-current_version,12.60 LDLIBS = -Wl,-framework,AppKit # this is needed for x86_64 - cross-gcc might not add it. #LDLIBS += -Wl,-lbundle1.o diff --git a/src/Makefile.linux b/src/Makefile.linux index 183bff4db..2a83f4fc8 100644 --- a/src/Makefile.linux +++ b/src/Makefile.linux @@ -16,7 +16,7 @@ LDFLAGS = -shared -Wl,-soname,libSDL-1.2.so.0 LDFLAGS+= -Wl,--no-undefined LDLIBS = -ldl -SHLIB = libSDL-1.2.so.1.2.59 +SHLIB = libSDL-1.2.so.1.2.60 OBJ = SDL12_compat.o diff --git a/src/Makefile.os2 b/src/Makefile.os2 index 39cbf72f1..37cc11790 100644 --- a/src/Makefile.os2 +++ b/src/Makefile.os2 @@ -5,7 +5,7 @@ !endif DLLNAME = SDL12 -VERSION = 1.2.59 +VERSION = 1.2.60 # change SDL2INC to point to the SDL2 headers SDL2INC = include diff --git a/src/Makefile.w32 b/src/Makefile.w32 index fc95a8e43..3aa55a02c 100644 --- a/src/Makefile.w32 +++ b/src/Makefile.w32 @@ -5,7 +5,7 @@ !endif DLLNAME = SDL -VERSION = 1.2.59 +VERSION = 1.2.60 # change SDL2INC to point to the SDL2 headers SDL2INC = include diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 70427258a..17e8595f6 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -28,7 +28,7 @@ * should be way ahead of what SDL-1.2 Classic would report, so apps can * decide if they're running under the compat layer, if they really care. */ -#define SDL12_COMPAT_VERSION 59 +#define SDL12_COMPAT_VERSION 60 #include #include diff --git a/src/version.rc b/src/version.rc index 0ed2e2fb7..d7cae5f16 100644 --- a/src/version.rc +++ b/src/version.rc @@ -3,8 +3,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,2,59,0 - PRODUCTVERSION 1,2,59,0 + FILEVERSION 1,2,60,0 + PRODUCTVERSION 1,2,60,0 FILEFLAGSMASK 0x3fL FILEFLAGS 0x0L FILEOS 0x40004L @@ -17,12 +17,12 @@ BEGIN BEGIN VALUE "CompanyName", "\0" VALUE "FileDescription", "SDL\0" - VALUE "FileVersion", "1, 2, 59, 0\0" + VALUE "FileVersion", "1, 2, 60, 0\0" VALUE "InternalName", "SDL\0" VALUE "LegalCopyright", "Copyright © 2022 Sam Lantinga\0" VALUE "OriginalFilename", "SDL.dll\0" VALUE "ProductName", "Simple DirectMedia Layer 1.2 wrapper\0" - VALUE "ProductVersion", "1, 2, 59, 0\0" + VALUE "ProductVersion", "1, 2, 60, 0\0" END END BLOCK "VarFileInfo" From 883b629995e998e04b2ccd80a2c3ada46b0ce093 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 24 Oct 2022 14:27:17 -0400 Subject: [PATCH 409/606] Bumped version to 1.2.61 for future development towards a 1.2.62 release. --- CMakeLists.txt | 4 ++-- include/SDL/SDL_version.h | 2 +- src/Makefile.darwin | 2 +- src/Makefile.linux | 2 +- src/Makefile.os2 | 2 +- src/Makefile.w32 | 2 +- src/SDL12_compat.c | 2 +- src/version.rc | 8 ++++---- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 57c0e9371..9ed261242 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.0.0) project(sdl12_compat - VERSION 1.2.60 + VERSION 1.2.61 LANGUAGES C) option(SDL12TESTS "Enable to build SDL-1.2 test programs" ON) @@ -33,7 +33,7 @@ if(APPLE) # Xcode project file uses 1.0.0, but it's more compatible to use the # higher version. set(DYLIB_COMPAT_VERSION 12.0.0 CACHE STRING "library compatibility version") - set(DYLIB_CURRENT_VERSION 12.60.0 CACHE STRING "library current version") + set(DYLIB_CURRENT_VERSION 12.61.0 CACHE STRING "library current version") include_directories("/opt/X11/include") # hack. if(CMAKE_VERSION VERSION_LESS 3.9) else() diff --git a/include/SDL/SDL_version.h b/include/SDL/SDL_version.h index 2715320fc..db5d25c0a 100644 --- a/include/SDL/SDL_version.h +++ b/include/SDL/SDL_version.h @@ -33,7 +33,7 @@ real SDL-1.2 available to you. */ /* We bumped the patchlevel to 50 for sdl12-compat */ #define SDL_MAJOR_VERSION 1 #define SDL_MINOR_VERSION 2 -#define SDL_PATCHLEVEL 60 +#define SDL_PATCHLEVEL 61 typedef struct SDL_version { diff --git a/src/Makefile.darwin b/src/Makefile.darwin index 0edb230f1..6d48386ef 100644 --- a/src/Makefile.darwin +++ b/src/Makefile.darwin @@ -18,7 +18,7 @@ CFLAGS = -mmacosx-version-min=10.6 -fPIC -O3 -Wall LDFLAGS = -mmacosx-version-min=10.6 -dynamiclib -Wl,-undefined,error -Wl,-single_module #LDFLAGS+= -Wl,-headerpad_max_install_names LDFLAGS+= -Wl,-install_name,"/usr/local/lib/$(DYLIB)" -LDFLAGS+= -Wl,-compatibility_version,1.0 -Wl,-current_version,12.60 +LDFLAGS+= -Wl,-compatibility_version,1.0 -Wl,-current_version,12.61 LDLIBS = -Wl,-framework,AppKit # this is needed for x86_64 - cross-gcc might not add it. #LDLIBS += -Wl,-lbundle1.o diff --git a/src/Makefile.linux b/src/Makefile.linux index 2a83f4fc8..01c4b4c39 100644 --- a/src/Makefile.linux +++ b/src/Makefile.linux @@ -16,7 +16,7 @@ LDFLAGS = -shared -Wl,-soname,libSDL-1.2.so.0 LDFLAGS+= -Wl,--no-undefined LDLIBS = -ldl -SHLIB = libSDL-1.2.so.1.2.60 +SHLIB = libSDL-1.2.so.1.2.61 OBJ = SDL12_compat.o diff --git a/src/Makefile.os2 b/src/Makefile.os2 index 37cc11790..8102655e5 100644 --- a/src/Makefile.os2 +++ b/src/Makefile.os2 @@ -5,7 +5,7 @@ !endif DLLNAME = SDL12 -VERSION = 1.2.60 +VERSION = 1.2.61 # change SDL2INC to point to the SDL2 headers SDL2INC = include diff --git a/src/Makefile.w32 b/src/Makefile.w32 index 3aa55a02c..2c3e4f639 100644 --- a/src/Makefile.w32 +++ b/src/Makefile.w32 @@ -5,7 +5,7 @@ !endif DLLNAME = SDL -VERSION = 1.2.60 +VERSION = 1.2.61 # change SDL2INC to point to the SDL2 headers SDL2INC = include diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 17e8595f6..64ba56f90 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -28,7 +28,7 @@ * should be way ahead of what SDL-1.2 Classic would report, so apps can * decide if they're running under the compat layer, if they really care. */ -#define SDL12_COMPAT_VERSION 60 +#define SDL12_COMPAT_VERSION 61 #include #include diff --git a/src/version.rc b/src/version.rc index d7cae5f16..b83fd2b18 100644 --- a/src/version.rc +++ b/src/version.rc @@ -3,8 +3,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,2,60,0 - PRODUCTVERSION 1,2,60,0 + FILEVERSION 1,2,61,0 + PRODUCTVERSION 1,2,61,0 FILEFLAGSMASK 0x3fL FILEFLAGS 0x0L FILEOS 0x40004L @@ -17,12 +17,12 @@ BEGIN BEGIN VALUE "CompanyName", "\0" VALUE "FileDescription", "SDL\0" - VALUE "FileVersion", "1, 2, 60, 0\0" + VALUE "FileVersion", "1, 2, 61, 0\0" VALUE "InternalName", "SDL\0" VALUE "LegalCopyright", "Copyright © 2022 Sam Lantinga\0" VALUE "OriginalFilename", "SDL.dll\0" VALUE "ProductName", "Simple DirectMedia Layer 1.2 wrapper\0" - VALUE "ProductVersion", "1, 2, 60, 0\0" + VALUE "ProductVersion", "1, 2, 61, 0\0" END END BLOCK "VarFileInfo" From 023e81237c9cc463e7761a332d517bae2318a2c5 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 24 Oct 2022 14:44:13 -0400 Subject: [PATCH 410/606] HOW_TO_TEST_GAMES: Added note on setgid binaries. --- HOW_TO_TEST_GAMES.md | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/HOW_TO_TEST_GAMES.md b/HOW_TO_TEST_GAMES.md index 74c64b458..8b37df5c6 100644 --- a/HOW_TO_TEST_GAMES.md +++ b/HOW_TO_TEST_GAMES.md @@ -42,7 +42,37 @@ Either overwrite the copy of SDL-1.2 that the game uses with sdl12-compat, or (on Linux) export LD_LIBRARY_PATH to point to your copy, so the system will favor it when loading libraries. - +## Watch out for setuid/setgid binaries! + +On Linux, if you're testing a binary that's setgid to a "games" group (which +we ran into several times with Debian packages), or setuid root or whatever, +then the system will ignore the LD_LIBRARY_PATH variable, as a security +measure. + +The reason some games are packaged like this is usually because they want to +write to a high score list in a global, shared directory. Often times the +games will just carry on if they fail to do so. + +There are several ways to bypass this: + +- On some distros, you can run `ld.so` directly: + ```bash + LD_LIBRARY_PATH=/where/i/can/find/sdl12-compat ld.so /usr/games/mygame + ``` +- You can remove the setgid bit: + ```bash + # (it's `u-s` for the setuid bit) + sudo chmod g-s /usr/games/mygame + ``` +- You can install sdl12-compat system-wide, so the game uses that + instead of SDL 1.2 by default. +- If you don't have root access at all, you can try to copy the game + somewhere else or install a personal copy, or build from source code, + but these are drastic measures. + +Definitely read the next section ("Am I actually running sdl12-compat?") in +these scenarios to make sure you ended up with the right library! + ## Am I actually running sdl12-compat? The easiest way to know is to set some environment variables: From 77892a1ef5260fe78e593c8337dbe98874ff336c Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Tue, 25 Oct 2022 15:56:50 +0300 Subject: [PATCH 411/606] fix SDL12COMPAT_MAX_VIDMODE, .. was broken by commit 7be4b3c99a436e360a43aefc929087c46cdadee9 --- src/SDL12_compat.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 64ba56f90..1123cc91f 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -2119,6 +2119,8 @@ Init12VidModes(void) SDL_sscanf(maxmodestr, "%ux%u", &w, &h); if (w > 0xFFFF) w = 0xFFFF; if (h > 0xFFFF) h = 0xFFFF; + maxw = w; + maxh = h; } for (i = 0; i < total; ++i) { From 1c6b5baf3923e5afcd115e00273d9d7ffcb22956 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 17 Nov 2022 01:11:24 -0800 Subject: [PATCH 412/606] SDL does support 1 and 4 bit surfaces, so allow these depths 1-bit bitmap surfaces are used by Maelstrom for rendering text, for example Fixes https://github.com/libsdl-org/sdl12-compat/issues/274 --- src/SDL12_compat.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 1123cc91f..6964e2b7d 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -4992,16 +4992,16 @@ SDL_CreateRGBSurface(Uint32 flags12, int width, int height, int depth, Uint32 Rm } /* !!! FIXME: this isn't strictly correct, but SDL2 doesn't support - !!! FIXME: surfaces smaller than 8 bits, and this lets at - !!! FIXME: least one game function correctly. */ - if (depth < 8) { + !!! FIXME: arbitrary depths smaller than 8 bits, and this lets at + !!! FIXME: least one game (rockdodger) function correctly. */ + if (depth < 8 && depth != 1 && depth != 4) { if (WantDebugLogging) { SDL20_Log("This app is creating an %d-bit SDL_Surface, but we are bumping it to 8-bits. If you see rendering issues, please report them!", depth); } depth = 8; } - if (depth == 8) { /* don't pass masks to SDL2 for 8-bit surfaces, it'll cause problems. */ + if (depth <= 8) { /* don't pass masks to SDL2 for <= 8-bit surfaces, it'll cause problems. */ surface20 = SDL20_CreateRGBSurface(0, width, height, depth, 0, 0, 0, 0); } else { surface20 = SDL20_CreateRGBSurface(0, width, height, depth, Rmask, Gmask, Bmask, Amask); From 683234e8708a081224942181710ca5dd3cee409e Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 17 Nov 2022 07:55:07 -0800 Subject: [PATCH 413/606] Fixed infinite loop in SDL_FreeYUVOverlay() Fixes https://github.com/libsdl-org/sdl12-compat/issues/275 --- src/SDL12_compat.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 6964e2b7d..fb657a6ba 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -7535,6 +7535,7 @@ SDL_FreeYUVOverlay(SDL12_Overlay *overlay12) if (overlay->overlay12 == overlay12) { overlay->overlay12 = NULL; /* don't try to draw this later. */ } + overlay = overlay->next; } if (renderer) { From 616e81294c04ba7d8523034b78c64c8f64c5c181 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 17 Nov 2022 13:46:38 -0500 Subject: [PATCH 414/606] quirks: Turn off OpenGL scaling for Quake 2 XP. Fixes #273. --- src/SDL12_compat.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index fb657a6ba..a6f0bb3e8 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1194,6 +1194,9 @@ static QuirkEntryType quirks[] = { {"Awesomenauts.bin.x86", "SDL12COMPAT_OPENGL_SCALING", "0"}, {"Awesomenauts.bin.x86", "SDL12COMPAT_FORCE_GL_SWAPBUFFER_CONTEXT", "1"}, + /* Quake 2 XP uses FBOs and doesn't use SDL_GL_GetProcAddress to get the entry points. */ + {"quake2xp", "SDL12COMPAT_OPENGL_SCALING", "0"}, + /* Braid uses Cg, which uses glXGetProcAddress(). */ {"braid", "SDL12COMPAT_OPENGL_SCALING", "0"}, From 76a1af147ea87bca20358ad54912a3f620115db2 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 17 Nov 2022 14:58:31 -0500 Subject: [PATCH 415/606] quirks: quake2xp now uses SDL_GL_GetProcAddress, so no quirk needed! Reference Issue #273. --- src/SDL12_compat.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index a6f0bb3e8..fb657a6ba 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1194,9 +1194,6 @@ static QuirkEntryType quirks[] = { {"Awesomenauts.bin.x86", "SDL12COMPAT_OPENGL_SCALING", "0"}, {"Awesomenauts.bin.x86", "SDL12COMPAT_FORCE_GL_SWAPBUFFER_CONTEXT", "1"}, - /* Quake 2 XP uses FBOs and doesn't use SDL_GL_GetProcAddress to get the entry points. */ - {"quake2xp", "SDL12COMPAT_OPENGL_SCALING", "0"}, - /* Braid uses Cg, which uses glXGetProcAddress(). */ {"braid", "SDL12COMPAT_OPENGL_SCALING", "0"}, From f58ff7cf742afaae84a2fdbbafe67d71a8c11780 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 18 Nov 2022 16:36:11 -0500 Subject: [PATCH 416/606] audio: Add a quirk to mimick SDL 1.2's audio converters more closely. In practice, you _don't_ want this; the resampler is extremely low quality and will overflow buffers if the frequency conversion isn't a multiple of two (just like SDL 1.2), but it works if the app allocates its conversion buffer incorrectly, and it's possible that some app relies on the quirky conversion in some form, too. Fixes #232. --- src/SDL12_compat.c | 199 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 190 insertions(+), 9 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index fb657a6ba..d23583458 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -875,9 +875,13 @@ typedef struct } dev; } SDL12_Joystick; + +struct SDL12_AudioCVT; +typedef void (SDLCALL *SDL12_AudioCVTFilter)(struct SDL12_AudioCVT *cvt, Uint16 format); + /* this is identical to SDL2, except SDL2 forced the structure packing in some instances, so we can't passthrough without converting the struct. :( */ -typedef struct +typedef struct SDL12_AudioCVT { int needed; Uint16 src_format; @@ -888,7 +892,7 @@ typedef struct int len_cvt; int len_mult; double len_ratio; - void (SDLCALL *filters[10])(struct SDL_AudioCVT *cvt, Uint16 format); + SDL12_AudioCVTFilter filters[10]; int filter_index; } SDL12_AudioCVT; @@ -1028,6 +1032,7 @@ static unsigned long SetVideoModeThread = 0; static SDL_bool VideoSurfaceUpdatedInBackgroundThread = SDL_FALSE; static SDL_bool AllowThreadedDraws = SDL_FALSE; static SDL_bool AllowThreadedPumps = SDL_FALSE; +static SDL_bool WantCompatibilityAudioCVT = SDL_FALSE; /* This is a KEYDOWN event which is being held for a follow-up TEXTINPUT */ @@ -1216,6 +1221,9 @@ static QuirkEntryType quirks[] = { {"scorched3d", "SDL12COMPAT_OPENGL_SCALING", "0"}, {"scorched3dc", "SDL12COMPAT_OPENGL_SCALING", "0"}, + /* boswars has a bug where SDL_AudioCVT must not require extra buffer space. See Issue #232. */ + {"boswars", "SDL12COMPAT_COMPATIBILITY_AUDIOCVT", "1"}, + /* The 32-bit Steam build only of Multiwinia Quits but doesn't re-Init */ {"multiwinia.bin.x86", "SDL12COMPAT_NO_QUIT_VIDEO", "1"} #else @@ -2350,6 +2358,12 @@ SDL_VideoInit(const char *driver, Uint32 flags) return retval; } +static void +Init12Audio(void) +{ + WantCompatibilityAudioCVT = SDL12Compat_GetHintBoolean("SDL12COMPAT_COMPATIBILITY_AUDIOCVT", SDL_TRUE); +} + static void InitializeCDSubsystem(void); static void QuitCDSubsystem(void); @@ -2429,6 +2443,10 @@ SDL_InitSubSystem(Uint32 sdl12flags) } #endif + if ((rc == 0) && (sdl20flags & SDL_INIT_AUDIO)) { + Init12Audio(); + } + if ((rc == 0) && (sdl20flags & SDL_INIT_JOYSTICK)) { Init12Joystick(); /* if this fails, we just won't report any sticks. */ } @@ -9382,22 +9400,185 @@ AudioCVT20to12(const SDL_AudioCVT *cvt20, SDL12_AudioCVT *cvt12) return cvt12; } +static void SDLCALL +CompatibilityCVT_RunStream(SDL12_AudioCVT *cvt12, Uint16 format) +{ + const size_t channel_mash = (size_t) cvt12->filters[SDL_arraysize(cvt12->filters) - 1]; + const Uint8 src_channels = (Uint8) (channel_mash & 0xFF); + const Uint8 dst_channels = (Uint8) ((channel_mash >> 8) & 0xFF); + + /* use an audiostream, so we can allocate a dynamic buffer for the work, even if the app screwed up their allocation. */ + SDL_AudioStream *stream = SDL20_NewAudioStream(format, src_channels, 44100, cvt12->dst_format, dst_channels, 44100); /* don't resample here! */ + if (stream == NULL) { + return; /* oh well. */ + } + + if ((SDL20_AudioStreamPut(stream, cvt12->buf, cvt12->len_cvt) == -1) || (SDL20_AudioStreamFlush(stream) == -1)) { /* probably out of memory if failed. */ + SDL20_FreeAudioStream(stream); + return; /* oh well. */ + } + + cvt12->len_cvt = SDL20_AudioStreamAvailable(stream); + SDL20_AudioStreamGet(stream, cvt12->buf, cvt12->len_cvt); + SDL20_FreeAudioStream(stream); + + if (cvt12->filters[++cvt12->filter_index]) { + cvt12->filters[cvt12->filter_index](cvt12, cvt12->dst_format); + } +} + +/* this is an extremely low-quality resampler: it only doubles or halves the + sample rate and offers no interpolation...but it's also how SDL 1.2 did it. + Notably: it can resample in-place, so this avoids bugs in apps that don't + set up SDL_AudioCVT's buffer correctly, or expect this weird 1.2 behavior + for whatever reason. */ +static void SDLCALL +CompatibilityCVT_Resampler(SDL12_AudioCVT *cvt12, Uint16 format) +{ + const int bitsize = (int) SDL_AUDIO_BITSIZE(format); + int i; + + SDL_assert((bitsize == 8) || (bitsize == 16)); /* there were no 32-bit audio types in 1.2. */ + + if (cvt12->rate_incr > 0.0) { /* upsampling */ + /*printf("2x Upsampling!\n");*/ + #define DO_RESAMPLE(typ) \ + const typ *src = (const typ *) (cvt12->buf + cvt12->len_cvt); \ + typ *dst = (typ *) (cvt12->buf + (cvt12->len_cvt * 2)); \ + for (i = cvt12->len_cvt; i; i--) { \ + const typ sample = *(--src); \ + dst -= 2; \ + dst[0] = dst[1] = sample; \ + } + if (bitsize == 8) { + DO_RESAMPLE(Uint8); + } else if (bitsize == 16) { + DO_RESAMPLE(Uint16); + } + #undef DO_RESAMPLE + cvt12->len_cvt *= 2; + } else { /* downsampling. */ + /*printf("2x Downsampling!\n");*/ + #define DO_RESAMPLE(typ) \ + const typ *src = (const typ *) (cvt12->buf + cvt12->len_cvt); \ + typ *dst = (typ *) (cvt12->buf + (cvt12->len_cvt * 2)); \ + for (i = cvt12->len_cvt / (sizeof (typ) * 2); i; i--, src += 2) { \ + *(dst++) = *src; \ + } + if (bitsize == 8) { + DO_RESAMPLE(Uint8); + } else if (bitsize == 16) { + DO_RESAMPLE(Uint16); + } + #undef DO_RESAMPLE + cvt12->len_cvt /= 2; + } + + if (cvt12->filters[++cvt12->filter_index]) { + cvt12->filters[cvt12->filter_index](cvt12, format); + } +} + DECLSPEC12 int SDLCALL SDL_BuildAudioCVT(SDL12_AudioCVT *cvt12, Uint16 src_format, Uint8 src_channels, int src_rate, Uint16 dst_format, Uint8 dst_channels, int dst_rate) { - SDL_AudioCVT cvt20; - const int retval = SDL20_BuildAudioCVT(&cvt20, src_format, src_channels, src_rate, dst_format, dst_channels, dst_rate); - AudioCVT20to12(&cvt20, cvt12); /* SDL 1.2 derefences cvt12 without checking for NULL */ + int retval = 0; + + SDL_zerop(cvt12); /* SDL 1.2 derefences cvt12 without checking for NULL */ + + if (!WantCompatibilityAudioCVT) { + SDL_AudioCVT cvt20; + retval = SDL20_BuildAudioCVT(&cvt20, src_format, src_channels, src_rate, dst_format, dst_channels, dst_rate); + AudioCVT20to12(&cvt20, cvt12); + } else { + const size_t channel_mash = ((size_t) src_channels) | (((size_t) dst_channels) << 8); + + if ((src_format == dst_format) && (src_channels == dst_channels) && (src_rate == dst_rate)) { + return 0; /* no conversion needed. */ + } + + cvt12->needed = 1; + cvt12->len_mult = 1; + cvt12->len_ratio = 1.0; + cvt12->src_format = src_format; + cvt12->dst_format = dst_format; + + if ((src_format != dst_format) || (src_channels != dst_channels)) { + if (src_format != dst_format) { + /* there are only 8 and 16 bit formats in SDL 1.2 */ + if (SDL_AUDIO_BITSIZE(src_format) < SDL_AUDIO_BITSIZE(dst_format)) { + cvt12->len_mult *= 2; + cvt12->len_ratio *= 2.0; + } else { + cvt12->len_ratio /= 2.0; + } + } + + /* SDL 1.2 only supported 1, 2, 4, and 6 channels, and would fail to convert between 4 and 6 at all. :O */ + if (src_channels < dst_channels) { + const int diff = (int) (dst_channels / src_channels); + cvt12->len_mult *= diff; + cvt12->len_ratio *= (double) diff; + } else if (src_channels > dst_channels) { + const int diff = (int) (src_channels / dst_channels); + cvt12->len_ratio /= (double) diff; + } + + cvt12->filters[cvt12->filter_index++] = CompatibilityCVT_RunStream; + cvt12->filters[SDL_arraysize(cvt12->filters) - 1] = (SDL12_AudioCVTFilter) channel_mash; /* cheat by hiding this info at end of array. */ + } + + if (src_rate != dst_rate) { + Uint32 hi_rate = src_rate; + Uint32 lo_rate = dst_rate; + int len_mult = 1; + double len_ratio = 0.5; + + if (src_rate < dst_rate) { /* flip everything. */ + hi_rate = dst_rate; + lo_rate = src_rate; + len_mult = 2; + len_ratio = 2.0; + } + + while (((lo_rate * 2) / 100) <= (hi_rate / 100)) { /* this is what SDL 1.2 does. *shrug* */ + if (cvt12->filter_index >= (SDL_arraysize(cvt12->filters) - 2)) { + return SDL20_SetError("Too many conversion filters needed"); + } + cvt12->filters[cvt12->filter_index++] = CompatibilityCVT_Resampler; + cvt12->len_mult *= len_mult; + lo_rate *= 2; + cvt12->len_ratio *= len_ratio; + } + + cvt12->rate_incr = ((double) src_rate) / ((double) dst_rate); + } + + retval = 1; /* conversion definitely needed. */ + } + return retval; } DECLSPEC12 int SDLCALL SDL_ConvertAudio(SDL12_AudioCVT *cvt12) { - /* neither SDL 1.2 nor 2.0 makes sure cvt12 isn't NULL here. :/ */ - SDL_AudioCVT cvt20; - const int retval = SDL20_ConvertAudio(AudioCVT12to20(cvt12, &cvt20)); - AudioCVT20to12(&cvt20, cvt12); + int retval = 0; + + if (!cvt12->buf) { /* neither SDL 1.2 nor 2.0 makes sure cvt12 isn't NULL here. :/ */ + retval = SDL20_SetError("No buffer allocated for conversion"); + } else if (!WantCompatibilityAudioCVT) { + SDL_AudioCVT cvt20; + retval = SDL20_ConvertAudio(AudioCVT12to20(cvt12, &cvt20)); + AudioCVT20to12(&cvt20, cvt12); + } else { + cvt12->len_cvt = cvt12->len; + cvt12->filter_index = 0; + if (cvt12->filters[0]) { + cvt12->filters[0](cvt12, cvt12->src_format); + } + } + return retval; } From 10a88ff2cc75c1151b4d365f79edc87f9ce2cc1f Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 18 Nov 2022 16:48:02 -0500 Subject: [PATCH 417/606] quirks: SDL12COMPAT_COMPATIBILITY_AUDIOCVT should default to off. --- src/SDL12_compat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index d23583458..b3f03d2f8 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -2361,7 +2361,7 @@ SDL_VideoInit(const char *driver, Uint32 flags) static void Init12Audio(void) { - WantCompatibilityAudioCVT = SDL12Compat_GetHintBoolean("SDL12COMPAT_COMPATIBILITY_AUDIOCVT", SDL_TRUE); + WantCompatibilityAudioCVT = SDL12Compat_GetHintBoolean("SDL12COMPAT_COMPATIBILITY_AUDIOCVT", SDL_FALSE); } From cc5c30984d8cffff056857dc62f337b962f20583 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 18 Nov 2022 18:56:10 -0500 Subject: [PATCH 418/606] audio: Fixed logic bug in compatibility resampler. --- src/SDL12_compat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index b3f03d2f8..82e02cd23 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -9445,7 +9445,7 @@ CompatibilityCVT_Resampler(SDL12_AudioCVT *cvt12, Uint16 format) #define DO_RESAMPLE(typ) \ const typ *src = (const typ *) (cvt12->buf + cvt12->len_cvt); \ typ *dst = (typ *) (cvt12->buf + (cvt12->len_cvt * 2)); \ - for (i = cvt12->len_cvt; i; i--) { \ + for (i = cvt12->len_cvt / sizeof (typ); i; i--) { \ const typ sample = *(--src); \ dst -= 2; \ dst[0] = dst[1] = sample; \ From 178fe4ce85b144fff1b016f768c69b9dd76dcafa Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 18 Nov 2022 18:56:36 -0500 Subject: [PATCH 419/606] quirks: Added SDL12COMPAT_COMPATIBILITY_AUDIOCVT=1 to "fillets" Fixes #234. --- src/SDL12_compat.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 82e02cd23..6cc9a4376 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1215,7 +1215,9 @@ static QuirkEntryType quirks[] = { {"tucnak", "SDL_FRAMEBUFFER_ACCELERATION", "false"}, /* looks for X11 display and does unnecessary X11 things. Causes problems with SDL2/x11. */ + /* also has some issue with audio conversion I didn't look more closely at. */ {"fillets", "SDL12COMPAT_ALLOW_SYSWM", "0"}, + {"fillets", "SDL12COMPAT_COMPATIBILITY_AUDIOCVT", "1"}, /* doesn't render with GL scaling enabled */ {"scorched3d", "SDL12COMPAT_OPENGL_SCALING", "0"}, From 209ebaec06d37d46cb79e4ded1b549b5b0fb485e Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 18 Nov 2022 19:22:07 -0500 Subject: [PATCH 420/606] debugging: Make note of the binary name we see. This is useful when you go to add a quirk for "mygame" but it turns out that name is just a script that runs "mygame.bin" or whatever. --- src/SDL12_compat.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 6cc9a4376..d195ca224 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1326,6 +1326,10 @@ SDL12Compat_ApplyQuirks(SDL_bool force_x11) const char *exe_name = SDL12Compat_GetExeName(); int i; + if (WantDebugLogging) { + SDL20_Log("This app appears to be named '%s'", exe_name); + } + #ifdef __linux__ if (force_x11) { const char *videodriver_env = SDL20_getenv("SDL_VIDEODRIVER"); From fe0713a5a7c3266a4b0fe870dcbcbb748fff324b Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 18 Nov 2022 19:23:00 -0500 Subject: [PATCH 421/606] audio: fixed compatibility downsampler. --- src/SDL12_compat.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index d195ca224..298534d4c 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -9446,7 +9446,7 @@ CompatibilityCVT_Resampler(SDL12_AudioCVT *cvt12, Uint16 format) SDL_assert((bitsize == 8) || (bitsize == 16)); /* there were no 32-bit audio types in 1.2. */ - if (cvt12->rate_incr > 0.0) { /* upsampling */ + if (cvt12->rate_incr < 1.0) { /* upsampling */ /*printf("2x Upsampling!\n");*/ #define DO_RESAMPLE(typ) \ const typ *src = (const typ *) (cvt12->buf + cvt12->len_cvt); \ @@ -9466,8 +9466,8 @@ CompatibilityCVT_Resampler(SDL12_AudioCVT *cvt12, Uint16 format) } else { /* downsampling. */ /*printf("2x Downsampling!\n");*/ #define DO_RESAMPLE(typ) \ - const typ *src = (const typ *) (cvt12->buf + cvt12->len_cvt); \ - typ *dst = (typ *) (cvt12->buf + (cvt12->len_cvt * 2)); \ + const typ *src = (const typ *) cvt12->buf; \ + typ *dst = (typ *) cvt12->buf; \ for (i = cvt12->len_cvt / (sizeof (typ) * 2); i; i--, src += 2) { \ *(dst++) = *src; \ } From 8bc4b0e345770c3ec36e4100cd00128a18b3282e Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 18 Nov 2022 19:23:19 -0500 Subject: [PATCH 422/606] quirks: Add SDL12COMPAT_COMPATIBILITY_AUDIOCVT=1 to "pink-pony". Fixes #259. --- src/SDL12_compat.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 298534d4c..d861d1a03 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1219,6 +1219,10 @@ static QuirkEntryType quirks[] = { {"fillets", "SDL12COMPAT_ALLOW_SYSWM", "0"}, {"fillets", "SDL12COMPAT_COMPATIBILITY_AUDIOCVT", "1"}, + /* Misuses SDL_AudioCVT */ + {"pink-pony", "SDL12COMPAT_COMPATIBILITY_AUDIOCVT", "1"}, + {"pink-pony.bin", "SDL12COMPAT_COMPATIBILITY_AUDIOCVT", "1"}, + /* doesn't render with GL scaling enabled */ {"scorched3d", "SDL12COMPAT_OPENGL_SCALING", "0"}, {"scorched3dc", "SDL12COMPAT_OPENGL_SCALING", "0"}, From 484c6a8ca710f2e5c877426a2500275aa2a2c324 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 22 Nov 2022 22:29:33 -0500 Subject: [PATCH 423/606] Copyright was never updated for 2022. Still like five weeks left! --- include/SDL/SDL.h | 2 +- include/SDL/SDL_active.h | 2 +- include/SDL/SDL_audio.h | 2 +- include/SDL/SDL_byteorder.h | 2 +- include/SDL/SDL_cdrom.h | 2 +- include/SDL/SDL_config.h | 2 +- include/SDL/SDL_copying.h | 2 +- include/SDL/SDL_cpuinfo.h | 2 +- include/SDL/SDL_endian.h | 2 +- include/SDL/SDL_error.h | 2 +- include/SDL/SDL_events.h | 2 +- include/SDL/SDL_getenv.h | 2 +- include/SDL/SDL_joystick.h | 2 +- include/SDL/SDL_keyboard.h | 2 +- include/SDL/SDL_keysym.h | 2 +- include/SDL/SDL_loadso.h | 2 +- include/SDL/SDL_main.h | 2 +- include/SDL/SDL_mouse.h | 2 +- include/SDL/SDL_mutex.h | 2 +- include/SDL/SDL_name.h | 2 +- include/SDL/SDL_opengl.h | 2 +- include/SDL/SDL_platform.h | 2 +- include/SDL/SDL_quit.h | 2 +- include/SDL/SDL_rwops.h | 2 +- include/SDL/SDL_stdinc.h | 2 +- include/SDL/SDL_syswm.h | 2 +- include/SDL/SDL_thread.h | 2 +- include/SDL/SDL_timer.h | 2 +- include/SDL/SDL_types.h | 2 +- include/SDL/SDL_version.h | 2 +- include/SDL/SDL_video.h | 2 +- include/SDL/begin_code.h | 2 +- include/SDL/close_code.h | 2 +- src/SDL12_compat.c | 2 +- src/SDL12_compat_objc.m | 2 +- src/SDL20_include_wrapper.h | 2 +- src/SDL20_syms.h | 2 +- src/default_cursor.h | 2 +- src/x86_msvc.h | 2 +- 39 files changed, 39 insertions(+), 39 deletions(-) diff --git a/include/SDL/SDL.h b/include/SDL/SDL.h index f67e482ef..c6021e725 100644 --- a/include/SDL/SDL.h +++ b/include/SDL/SDL.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2021 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_active.h b/include/SDL/SDL_active.h index d4d44f00a..0d2059035 100644 --- a/include/SDL/SDL_active.h +++ b/include/SDL/SDL_active.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2021 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_audio.h b/include/SDL/SDL_audio.h index 19bf4ae8f..01de5bb08 100644 --- a/include/SDL/SDL_audio.h +++ b/include/SDL/SDL_audio.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2021 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_byteorder.h b/include/SDL/SDL_byteorder.h index 59a8bf380..a166a4d06 100644 --- a/include/SDL/SDL_byteorder.h +++ b/include/SDL/SDL_byteorder.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2021 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_cdrom.h b/include/SDL/SDL_cdrom.h index 49205b2dc..01747ebee 100644 --- a/include/SDL/SDL_cdrom.h +++ b/include/SDL/SDL_cdrom.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2021 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_config.h b/include/SDL/SDL_config.h index d76b2de08..afd04806c 100644 --- a/include/SDL/SDL_config.h +++ b/include/SDL/SDL_config.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2021 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_copying.h b/include/SDL/SDL_copying.h index 09d52f34a..a04763a1f 100644 --- a/include/SDL/SDL_copying.h +++ b/include/SDL/SDL_copying.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2021 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_cpuinfo.h b/include/SDL/SDL_cpuinfo.h index 2a570f095..df2c598a8 100644 --- a/include/SDL/SDL_cpuinfo.h +++ b/include/SDL/SDL_cpuinfo.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2021 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_endian.h b/include/SDL/SDL_endian.h index 94cbb5161..3c6f5c0a8 100644 --- a/include/SDL/SDL_endian.h +++ b/include/SDL/SDL_endian.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2021 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_error.h b/include/SDL/SDL_error.h index 66fad21f0..058fd5f6d 100644 --- a/include/SDL/SDL_error.h +++ b/include/SDL/SDL_error.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2021 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_events.h b/include/SDL/SDL_events.h index 4154b3e63..4d0fa8226 100644 --- a/include/SDL/SDL_events.h +++ b/include/SDL/SDL_events.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2021 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_getenv.h b/include/SDL/SDL_getenv.h index 9ffdc3e80..a27968d51 100644 --- a/include/SDL/SDL_getenv.h +++ b/include/SDL/SDL_getenv.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2021 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_joystick.h b/include/SDL/SDL_joystick.h index 9ce8fd45b..31336c02d 100644 --- a/include/SDL/SDL_joystick.h +++ b/include/SDL/SDL_joystick.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2021 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_keyboard.h b/include/SDL/SDL_keyboard.h index 0ea4faa6a..2e475b25e 100644 --- a/include/SDL/SDL_keyboard.h +++ b/include/SDL/SDL_keyboard.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2021 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_keysym.h b/include/SDL/SDL_keysym.h index 39c805f6f..d7e1ec3b4 100644 --- a/include/SDL/SDL_keysym.h +++ b/include/SDL/SDL_keysym.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2021 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_loadso.h b/include/SDL/SDL_loadso.h index 2d40b0c87..a0497eba3 100644 --- a/include/SDL/SDL_loadso.h +++ b/include/SDL/SDL_loadso.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2021 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_main.h b/include/SDL/SDL_main.h index 86052a651..814134946 100644 --- a/include/SDL/SDL_main.h +++ b/include/SDL/SDL_main.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2021 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_mouse.h b/include/SDL/SDL_mouse.h index 66f1552fd..b82e2d620 100644 --- a/include/SDL/SDL_mouse.h +++ b/include/SDL/SDL_mouse.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2021 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_mutex.h b/include/SDL/SDL_mutex.h index f60609c49..b2a854294 100644 --- a/include/SDL/SDL_mutex.h +++ b/include/SDL/SDL_mutex.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2021 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_name.h b/include/SDL/SDL_name.h index 1a63caff5..896d1202d 100644 --- a/include/SDL/SDL_name.h +++ b/include/SDL/SDL_name.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2021 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_opengl.h b/include/SDL/SDL_opengl.h index 1a33a905e..b3ee14a07 100644 --- a/include/SDL/SDL_opengl.h +++ b/include/SDL/SDL_opengl.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2021 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_platform.h b/include/SDL/SDL_platform.h index 4eea24dba..850bcca27 100644 --- a/include/SDL/SDL_platform.h +++ b/include/SDL/SDL_platform.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2021 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_quit.h b/include/SDL/SDL_quit.h index 61f3bada8..475bbb69f 100644 --- a/include/SDL/SDL_quit.h +++ b/include/SDL/SDL_quit.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2021 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_rwops.h b/include/SDL/SDL_rwops.h index 0ca9cfec3..d6a789d1d 100644 --- a/include/SDL/SDL_rwops.h +++ b/include/SDL/SDL_rwops.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2021 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_stdinc.h b/include/SDL/SDL_stdinc.h index d604b0392..5c62471a3 100644 --- a/include/SDL/SDL_stdinc.h +++ b/include/SDL/SDL_stdinc.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2021 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_syswm.h b/include/SDL/SDL_syswm.h index b8258c29d..dbb2e68fa 100644 --- a/include/SDL/SDL_syswm.h +++ b/include/SDL/SDL_syswm.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2021 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_thread.h b/include/SDL/SDL_thread.h index 906b2705c..5008ac266 100644 --- a/include/SDL/SDL_thread.h +++ b/include/SDL/SDL_thread.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2021 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_timer.h b/include/SDL/SDL_timer.h index 07ccb5f0d..224d62554 100644 --- a/include/SDL/SDL_timer.h +++ b/include/SDL/SDL_timer.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2021 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_types.h b/include/SDL/SDL_types.h index 9ffdc3e80..a27968d51 100644 --- a/include/SDL/SDL_types.h +++ b/include/SDL/SDL_types.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2021 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_version.h b/include/SDL/SDL_version.h index db5d25c0a..e74508788 100644 --- a/include/SDL/SDL_version.h +++ b/include/SDL/SDL_version.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2021 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_video.h b/include/SDL/SDL_video.h index 20b51d83c..67db72313 100644 --- a/include/SDL/SDL_video.h +++ b/include/SDL/SDL_video.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2021 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/begin_code.h b/include/SDL/begin_code.h index e2d093e5a..f7e1693ac 100644 --- a/include/SDL/begin_code.h +++ b/include/SDL/begin_code.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2021 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/close_code.h b/include/SDL/close_code.h index a7ad15977..b54c4530b 100644 --- a/include/SDL/close_code.h +++ b/include/SDL/close_code.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2021 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index d861d1a03..f7d96439e 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2021 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/SDL12_compat_objc.m b/src/SDL12_compat_objc.m index 79966d271..30b97b3fe 100644 --- a/src/SDL12_compat_objc.m +++ b/src/SDL12_compat_objc.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2021 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/SDL20_include_wrapper.h b/src/SDL20_include_wrapper.h index adea80acc..a1c21b1f3 100644 --- a/src/SDL20_include_wrapper.h +++ b/src/SDL20_include_wrapper.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2021 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/SDL20_syms.h b/src/SDL20_syms.h index cb54bdf0e..cb6f9deee 100644 --- a/src/SDL20_syms.h +++ b/src/SDL20_syms.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2021 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/default_cursor.h b/src/default_cursor.h index 0a888f4c8..c35e98ac9 100644 --- a/src/default_cursor.h +++ b/src/default_cursor.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2021 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/x86_msvc.h b/src/x86_msvc.h index 997d5a96f..5d5e0ac79 100644 --- a/src/x86_msvc.h +++ b/src/x86_msvc.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2021 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages From a3d1da652229ef7eb19ccebecd8a35ff749e4f59 Mon Sep 17 00:00:00 2001 From: David Gow Date: Sun, 27 Nov 2022 14:45:28 +0800 Subject: [PATCH 424/606] DisplayYUVOverlay: Don't update screen surface if clean Currently, if there are multiple SDL_DisplayYUVOverlay() calls in a row, we force an SDL_Flip() between them, in order to make sure that the screen is updated. However, this results in the non-YUV video surface also being updated, even if it otherwise wouldn't be. Instead, copy the code from all of the other places where we force an update of the screen, which checks if the surface is dirty, and if not calls PresentScreen() directly without updating the VideoSurface. (After checking we're in the correct thread, of course...) This hopefully fixes video artefacts in Alpha Centauri (bug #279) --- src/SDL12_compat.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index f7d96439e..968cc6318 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -7474,6 +7474,7 @@ SDL_DisplayYUVOverlay(SDL12_Overlay *overlay12, SDL12_Rect *dstrect12) QueuedOverlayItem *overlay; SDL12_YUVData *hwdata; SDL_Renderer *renderer = NULL; + const SDL_bool ThisIsSetVideoModeThread = (SDL20_ThreadID() == SetVideoModeThread) ? SDL_TRUE : SDL_FALSE; if (!overlay12) { return SDL20_InvalidParamError("overlay"); @@ -7485,7 +7486,15 @@ SDL_DisplayYUVOverlay(SDL12_Overlay *overlay12, SDL12_Rect *dstrect12) for (overlay = QueuedDisplayOverlays.next; overlay != NULL; overlay = overlay->next) { if (overlay->overlay12 == overlay12) { /* trying to draw the same overlay twice in one frame? Dump the current surface and overlays to the screen now. */ - SDL_Flip(VideoSurface12); + /* Force an update of the screen. */ + if (ThisIsSetVideoModeThread) { + if (VideoSurfaceUpdatedInBackgroundThread) { + SDL_Flip(VideoSurface12); /* this will update the texture and present. */ + } else if (VideoSurfacePresentTicks) { + PresentScreen(); + } + } + break; } } From e8de4b55eff752cd5fa80b37b1d1e4261bf11932 Mon Sep 17 00:00:00 2001 From: David Gow Date: Sun, 27 Nov 2022 14:52:48 +0800 Subject: [PATCH 425/606] Call PumpEvents in PresentScreen when SDL_EVENTTHREAD enabled At the moment, we "emulate" SDL_EVENTTHREAD by calling SDL_PumpEvents() in SDL_PeekEvent(). But some games don't even do this, so events aren't pumped at all, particularly while (e.g.) videos are playing, which is often just a tight SDL_DisplayYUVOverlay() loop. If we SDL_PumpEvents() from within PresentScreen(), we should at least get events as long as the screen is being updated. The complexity here is that SDL_PumpEvents() itself calls PresentScreen() to get a minimal framerate from things rendering directly to the front buffer. So we add a quick check to avoid SDL_PumpEvents() from entering infinite recursion by calling itself. Should fix the difficulty with skipping videos in Alpha Centauri mentioned in #278. --- src/SDL12_compat.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 968cc6318..bfa02f905 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -6593,6 +6593,17 @@ PresentScreen(void) return; } + /* We don't actually implement an event thread in sdl12-compat, but some + * games will only call SDL_PeepEvents(), which doesn't otherwise pump + * events, and get stuck when they've consumed all the events. + * + * Just pumping the event loop here simulates an event thread well enough + * for most things. + */ + if (EventThreadEnabled) { + SDL_PumpEvents(); + } + SDL20_RenderClear(renderer); SDL20_RenderCopy(renderer, VideoTexture20, NULL, NULL); @@ -6923,11 +6934,16 @@ SDL_PumpEvents(void) { const SDL_bool ThisIsSetVideoModeThread = (SDL20_ThreadID() == SetVideoModeThread) ? SDL_TRUE : SDL_FALSE; SDL_Event e; + static SDL_bool InPumpEvents = SDL_FALSE; if (!ThisIsSetVideoModeThread && !AllowThreadedPumps) { return; } + if (InPumpEvents) + return; + InPumpEvents = SDL_TRUE; + /* If the app is doing dirty rectangles, we set a flag and present the * screen surface when they pump for new events if we're close to 60Hz, * which we consider a sign that they are done rendering for the current @@ -6958,6 +6974,7 @@ SDL_PumpEvents(void) if (EventQueueMutex) { SDL20_UnlockMutex(EventQueueMutex); } + InPumpEvents = SDL_FALSE; } DECLSPEC12 void SDLCALL From 137d4515585efa145baca6bf52afd1eb702a6bbc Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sun, 27 Nov 2022 20:29:40 +0300 Subject: [PATCH 426/606] minor clean-up. --- src/SDL12_compat_objc.m | 5 +---- src/SDL20_include_wrapper.h | 11 +++++------ 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/src/SDL12_compat_objc.m b/src/SDL12_compat_objc.m index 30b97b3fe..ca46b5ee5 100644 --- a/src/SDL12_compat_objc.m +++ b/src/SDL12_compat_objc.m @@ -21,10 +21,7 @@ /* This file contains some macOS-specific support code */ -#define __BUILDING_SDL12_COMPAT__ 1 -#include "SDL.h" - -#ifdef __MACOSX__ +#ifdef __APPLE__ #include #if __GNUC__ >= 4 diff --git a/src/SDL20_include_wrapper.h b/src/SDL20_include_wrapper.h index a1c21b1f3..3f8461ef0 100644 --- a/src/SDL20_include_wrapper.h +++ b/src/SDL20_include_wrapper.h @@ -131,15 +131,14 @@ #define __BUILDING_SDL12_COMPAT__ 1 #include "SDL.h" -#include "SDL_syswm.h" /* includes windows.h for _WIN32, os2.h for __OS2__ */ +#include "SDL_syswm.h" /* includes windows.h or os2.h */ -/* Headers from SDL2 >= 2.0.7 needed for SDL_AudioStream: - */ +/* Headers from SDL2 >= 2.0.7 needed for SDL_AudioStream. */ #if !SDL_VERSION_ATLEAST(2,0,7) #error You need to compile against SDL >= 2.0.7 headers. #endif -/* Missing SDL_thread.h stuff (see above): */ +/* Missing SDL_thread.h stuff (see above) */ #if defined(_WIN32) || defined(__OS2__) typedef struct SDL_Thread SDL_Thread; typedef int (SDLCALL *SDL_ThreadFunction) (void*); @@ -152,7 +151,8 @@ typedef void (*pfnSDL_CurrentEndThread) (void); typedef UINT_PTR (__cdecl *pfnSDL_CurrentBeginThread) (void*, unsigned, unsigned (__stdcall *func)(void*), void*, unsigned, unsigned*); typedef void (__cdecl *pfnSDL_CurrentEndThread) (unsigned); -/* the following macros from Win32 SDK headers are harmful here: */ +/* the following macros from Win32 SDK headers are harmful here. */ +#undef CreateWindow #undef CreateThread #undef CreateSemaphore #undef CreateMutex @@ -431,4 +431,3 @@ typedef void (__cdecl *pfnSDL_CurrentEndThread) (unsigned); #endif /* vi: set ts=4 sw=4 expandtab: */ - From 3e81339b30bffb54cb0563a9bd6194ffedb2cce8 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Tue, 29 Nov 2022 23:10:50 +0300 Subject: [PATCH 427/606] Makefile.linux: adjust symlinks. --- src/Makefile.linux | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Makefile.linux b/src/Makefile.linux index 01c4b4c39..970f47b5c 100644 --- a/src/Makefile.linux +++ b/src/Makefile.linux @@ -27,9 +27,9 @@ all: $(SHLIB) $(SHLIB): $(OBJ) $(LD) -o $@ $(LDFLAGS) $(OBJ) $(LDLIBS) - ln -sf $(SHLIB) libSDL-1.2.so ln -sf $(SHLIB) libSDL-1.2.so.0 - ln -sf $(SHLIB) libSDL.so + ln -sf libSDL-1.2.so.0 libSDL-1.2.so + ln -sf libSDL-1.2.so.0 libSDL.so .c.o: $(CC) $(CFLAGS) $(CPPFLAGS) $(INCLUDES) -o $@ -c $< From 2bc46a0f9f400f9e6b2f8d52fc7378f90ca748f3 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Tue, 20 Dec 2022 00:47:20 +0300 Subject: [PATCH 428/606] Fix -Wsign-compare warnings. --- src/SDL12_compat.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index bfa02f905..8cbcf7304 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1619,7 +1619,7 @@ static int get_cpu_ext_features(void) { if (SDL20_HasMMX()) { int a, b, c, d; cpuid(0x80000000, a, b, c, d); - if (a >= 0x80000001) { + if ((unsigned int)a >= 0x80000001) { cpuid(0x80000001, a, b, c, d); cpu_ext_features = d; } @@ -9578,7 +9578,7 @@ SDL_BuildAudioCVT(SDL12_AudioCVT *cvt12, Uint16 src_format, Uint8 src_channels, } while (((lo_rate * 2) / 100) <= (hi_rate / 100)) { /* this is what SDL 1.2 does. *shrug* */ - if (cvt12->filter_index >= (SDL_arraysize(cvt12->filters) - 2)) { + if (cvt12->filter_index >= (int)(SDL_arraysize(cvt12->filters) - 2)) { return SDL20_SetError("Too many conversion filters needed"); } cvt12->filters[cvt12->filter_index++] = CompatibilityCVT_Resampler; From b35bb7c0867fb119e6d8c835bc57a4639c12e1e5 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 10 Jan 2023 20:14:00 -0500 Subject: [PATCH 429/606] video: Initialze the screen surface's pixels during SDL_SetVideoMode. Reference Issue #283. --- src/SDL12_compat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 8cbcf7304..64c3836c5 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -6195,7 +6195,7 @@ SetVideoModeImpl(int width, int height, int bpp, Uint32 flags12) } VideoSurface12->flags &= ~SDL12_OPENGL; - VideoSurface12->surface20->pixels = SDL20_malloc(height * VideoSurface12->pitch); + VideoSurface12->surface20->pixels = SDL20_calloc(height, VideoSurface12->pitch); VideoSurface12->pixels = VideoSurface12->surface20->pixels; if (!VideoSurface12->pixels) { SDL20_OutOfMemory(); From 86183bf42d74a967451483b89679ef099d4a4023 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 10 Jan 2023 20:50:12 -0500 Subject: [PATCH 430/606] video: Only pretend to lock the screen surface. This fixes rendering in xrick. Reference issue #283. --- src/SDL12_compat.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 64c3836c5..be11e1ef4 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -6483,18 +6483,25 @@ SDL_SetAlpha(SDL12_Surface *surface12, Uint32 flags12, Uint8 value) DECLSPEC12 int SDLCALL SDL_LockSurface(SDL12_Surface *surface12) { - const int retval = SDL20_LockSurface(surface12->surface20); - surface12->pixels = surface12->surface20->pixels; - surface12->pitch = surface12->surface20->pitch; + int retval = 0; + /* just pretend to lock for the screen surface, but ignore it. */ + if (surface12 != VideoSurface12) { + retval = SDL20_LockSurface(surface12->surface20); + surface12->pixels = surface12->surface20->pixels; + surface12->pitch = surface12->surface20->pitch; + } return retval; } DECLSPEC12 void SDLCALL SDL_UnlockSurface(SDL12_Surface *surface12) { - SDL20_UnlockSurface(surface12->surface20); - surface12->pixels = surface12->surface20->pixels; - surface12->pitch = surface12->surface20->pitch; + /* just pretend to lock for the screen surface, but ignore it. */ + if (surface12 != VideoSurface12) { + SDL20_UnlockSurface(surface12->surface20); + surface12->pixels = surface12->surface20->pixels; + surface12->pitch = surface12->surface20->pitch; + } } DECLSPEC12 int SDLCALL From f52d7787f9f513a5a2ba99d92678af39a9548458 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 11 Jan 2023 15:27:00 -0500 Subject: [PATCH 431/606] audio: Deal with non-seekable rwops in SDL_LoadWAV_RW. Fixes #283. --- src/SDL12_compat.c | 22 +++++++++++++++++++++- src/SDL20_syms.h | 1 + 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index be11e1ef4..219653cb4 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -8358,7 +8358,27 @@ SDL_LoadWAV_RW(SDL12_RWops *rwops12, int freerwops12, SDL_AudioSpec *spec, Uint8 **buf, Uint32 *len) { SDL_RWops *rwops20 = RWops12to20(rwops12); - SDL_AudioSpec *retval = SDL20_LoadWAV_RW(rwops20, freerwops12, spec, buf, len); + SDL_AudioSpec *retval = NULL; + + *buf = NULL; + + /* SDL2's LoadWAV requires a seekable stream, but SDL 1.2 didn't, + so if the stream appears unseekable, try to load it into a + memory rwops that we _can_ seek in */ + if (rwops20->seek(rwops20, 0, RW_SEEK_CUR) != -1) { /* if seekable */ + retval = SDL20_LoadWAV_RW(rwops20, freerwops12, spec, buf, len); + } else { + size_t datasize = 0; + void *buffer = SDL20_LoadFile_RW(rwops20, &datasize, freerwops12); + if (buffer) { + SDL_RWops *memrwops20 = SDL20_RWFromConstMem(buffer, (int) datasize); + if (memrwops20) { + retval = SDL20_LoadWAV_RW(memrwops20, 1, spec, buf, len); + } + SDL_free(buffer); + } + } + if (retval && retval->format & 0x20) { SDL20_SetError("Unsupported 32-bit PCM data format"); SDL20_FreeWAV(*buf); diff --git a/src/SDL20_syms.h b/src/SDL20_syms.h index cb6f9deee..a2dd92448 100644 --- a/src/SDL20_syms.h +++ b/src/SDL20_syms.h @@ -267,6 +267,7 @@ SDL20_SYM(SDL_RWops *,RWFromMem,(void *a, int b),(a,b),return) SDL20_SYM(SDL_RWops *,RWFromConstMem,(const void *a, int b),(a,b),return) SDL20_SYM(SDL_RWops *,AllocRW,(void),(),return) SDL20_SYM(void,FreeRW,(SDL_RWops *a),(a),) +SDL20_SYM(void *,LoadFile_RW,(SDL_RWops *a, size_t *b, int c),(a,b,c),return) SDL20_SYM_PASSTHROUGH(void *,malloc,(size_t a),(a),return) SDL20_SYM_PASSTHROUGH(void *,calloc,(size_t a, size_t b),(a,b),return) From db10d6fc01a2a567ddf58e9890b3bbeb6fa5c77c Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 13 Jan 2023 11:45:58 -0500 Subject: [PATCH 432/606] video: Fixed memory leak in video subsystem quit. Fixes #284. --- src/SDL12_compat.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 219653cb4..b8749d080 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -5430,10 +5430,11 @@ EndVidModeCreate(void) VideoPhysicalPalette20 = NULL; } if (VideoSurface12) { + SDL12_Surface *screen12 = VideoSurface12; SDL20_free(VideoSurface12->pixels); VideoSurface12->pixels = NULL; - SDL_FreeSurface(VideoSurface12); - VideoSurface12 = NULL; + VideoSurface12 = NULL; /* SDL_FreeSurface will ignore the screen surface, so NULL the global variable out. */ + SDL_FreeSurface(screen12); } if (VideoConvertSurface20) { SDL20_FreeSurface(VideoConvertSurface20); From 5e89e86519dfc9ed70738bcca5c9b72becbc07fa Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 13 Jan 2023 15:14:25 -0500 Subject: [PATCH 433/606] quirks: Don't let grafx2 access an X11 server directly. Fixes #282. --- src/SDL12_compat.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index b8749d080..7629c2913 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1230,6 +1230,9 @@ static QuirkEntryType quirks[] = { /* boswars has a bug where SDL_AudioCVT must not require extra buffer space. See Issue #232. */ {"boswars", "SDL12COMPAT_COMPATIBILITY_AUDIOCVT", "1"}, + /* grafx2 tries to do all sorts of stuff by talking directly to the X server, causing problems. */ + {"grafx2", "SDL12COMPAT_ALLOW_SYSWM", "0"}, + /* The 32-bit Steam build only of Multiwinia Quits but doesn't re-Init */ {"multiwinia.bin.x86", "SDL12COMPAT_NO_QUIT_VIDEO", "1"} #else From b2f7b7736b4adaba2805e5d2979c51676ee950ce Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 13 Jan 2023 15:19:39 -0500 Subject: [PATCH 434/606] video: Don't create a new VideoRendererLock if we already have one. Fixes #285. --- src/SDL12_compat.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 7629c2913..b9aa2eabe 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -6143,10 +6143,14 @@ SetVideoModeImpl(int width, int height, int bpp, Uint32 flags12) const SDL_bool want_vsync = (vsync_env && SDL20_atoi(vsync_env)) ? SDL_TRUE : SDL_FALSE; SDL_RendererInfo rinfo; SDL_assert(!VideoGLContext20); /* either a new window or we destroyed all this */ - VideoRendererLock = SDL20_CreateMutex(); + if (!VideoRendererLock) { - return EndVidModeCreate(); + VideoRendererLock = SDL20_CreateMutex(); + if (!VideoRendererLock) { + return EndVidModeCreate(); + } } + if (!VideoRenderer20 && want_vsync) { VideoRenderer20 = SDL20_CreateRenderer(VideoWindow20, -1, SDL_RENDERER_ACCELERATED|SDL_RENDERER_PRESENTVSYNC); } From 663c34b130383df2ba6674dc13657da9ca597cb7 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sat, 4 Feb 2023 01:55:50 +0300 Subject: [PATCH 435/606] several type / prototype fixes for SDL2 functions. --- src/SDL12_compat.c | 4 ++++ src/SDL20_syms.h | 8 ++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index b9aa2eabe..2af6547a4 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1513,6 +1513,10 @@ unsigned _System LibMain(unsigned hmod, unsigned termination) #error Please define an init procedure for your platform. #endif +/* Forward declarations */ +DECLSPEC12 void SDLCALL SDL_CloseAudio(void); +DECLSPEC12 void SDLCALL SDL_PumpEvents(void); + #ifdef _WIN32 /* SDL_main functions: * SDL2 doesn't define SDL_MAIN_NEEDED for _WIN32, diff --git a/src/SDL20_syms.h b/src/SDL20_syms.h index a2dd92448..23a97a9ce 100644 --- a/src/SDL20_syms.h +++ b/src/SDL20_syms.h @@ -46,7 +46,7 @@ SDL20_SYM_VARARGS(void,Log,(const char *fmt, ...)) SDL20_SYM(int,Init,(Uint32 a),(a),return) SDL20_SYM(int,InitSubSystem,(Uint32 a),(a),return) SDL20_SYM(Uint32,WasInit,(Uint32 a),(a),return) -SDL20_SYM(char*,GetError,(void),(),return) +SDL20_SYM(const char*,GetError,(void),(),return) SDL20_SYM_VARARGS(int,SetError,(const char *fmt, ...)) SDL20_SYM(const char *,GetHint,(const char *a),(a),return) @@ -114,7 +114,7 @@ SDL20_SYM(SDL_Surface *,ConvertSurface,(SDL_Surface *a, const SDL_PixelFormat *b SDL20_SYM(int,LockSurface,(SDL_Surface *a),(a),return) SDL20_SYM(void,UnlockSurface,(SDL_Surface *a),(a),) SDL20_SYM(int,UpperBlit,(SDL_Surface *a,const SDL_Rect *b,SDL_Surface *c, SDL_Rect *d),(a,b,c,d),return) -SDL20_SYM(int,LowerBlit,(SDL_Surface *a,const SDL_Rect *b,SDL_Surface *c, SDL_Rect *d),(a,b,c,d),return) +SDL20_SYM(int,LowerBlit,(SDL_Surface *a,SDL_Rect *b,SDL_Surface *c, SDL_Rect *d),(a,b,c,d),return) SDL20_SYM(int,SoftStretch,(SDL_Surface *a,const SDL_Rect *b,SDL_Surface *c,const SDL_Rect *d),(a,b,c,d),return) SDL20_SYM(int,SetColorKey,(SDL_Surface *a, int b, Uint32 c),(a,b,c),return) SDL20_SYM(int,GetColorKey,(SDL_Surface *a, Uint32 *b),(a,b),return) @@ -195,7 +195,7 @@ SDL20_SYM_PASSTHROUGH(int,CondWait,(SDL_cond *a, SDL_mutex *b),(a,b),return) SDL20_SYM_PASSTHROUGH(int,CondWaitTimeout,(SDL_cond *a, SDL_mutex *b, Uint32 c),(a,b,c),return) SDL20_SYM(int,AtomicGet,(SDL_atomic_t *a),(a),return) -SDL20_SYM(void,AtomicSet,(SDL_atomic_t *a, int b),(a,b),) +SDL20_SYM(int,AtomicSet,(SDL_atomic_t *a, int b),(a,b),return) SDL20_SYM(int,AtomicAdd,(SDL_atomic_t *a, int b),(a,b),return) SDL20_SYM(SDL_AudioSpec *,LoadWAV_RW,(SDL_RWops *a, int b, SDL_AudioSpec *c, Uint8 **d, Uint32 *e),(a,b,c,d,e),return) @@ -262,7 +262,7 @@ SDL20_SYM(void,LockJoysticks,(void),(),) SDL20_SYM(void,UnlockJoysticks,(void),(),) SDL20_SYM(SDL_RWops *,RWFromFile,(const char *a, const char *b),(a,b),return) -SDL20_SYM(SDL_RWops *,RWFromFP,(void *a, int b),(a,b),return) /* FILE* */ +SDL20_SYM(SDL_RWops *,RWFromFP,(void *a, SDL_bool b),(a,b),return) /* FILE* */ SDL20_SYM(SDL_RWops *,RWFromMem,(void *a, int b),(a,b),return) SDL20_SYM(SDL_RWops *,RWFromConstMem,(const void *a, int b),(a,b),return) SDL20_SYM(SDL_RWops *,AllocRW,(void),(),return) From f0b28aaae68dc41aca6299fd786799e1f200786a Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sat, 4 Feb 2023 17:01:02 +0300 Subject: [PATCH 436/606] clean-up --- src/SDL12_compat.c | 85 +++++++++++++++++++++++++++------------------- 1 file changed, 51 insertions(+), 34 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 2af6547a4..c9142bce6 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1872,7 +1872,8 @@ SDL_JoystickGetBall(SDL12_Joystick *stick12, int ball, int *dx, int *dy) { if (BogusJoystick(stick12)) { return 0; - } else if (JoysticksAreGameControllers) { + } + if (JoysticksAreGameControllers) { if (dx) { *dx = 0; } if (dy) { *dy = 0; } return SDL20_SetError("No joystick balls available"); @@ -2023,15 +2024,12 @@ GetVideoDisplay(void) } if (variable) { int preferred_display = SDL20_atoi(variable); - if (preferred_display < 0 || preferred_display >= SDL20_GetNumVideoDisplays()) { return 0; } - return SDL20_atoi(variable); - } else { - return 0; } + return 0; } /* returns true if mode1 should sort before mode2 */ @@ -2040,11 +2038,11 @@ VidModeSizeGreater(SDL12_Rect *mode1, SDL12_Rect *mode2) { if (mode1->w > mode2->w) { return 1; - } else if (mode2->w > mode1->w) { + } + if (mode2->w > mode1->w) { return 0; - } else { - return (mode1->h > mode2->h); } + return (mode1->h > mode2->h); } static int @@ -2666,9 +2664,8 @@ GetDriverName(const char *name, char *namebuf, int maxlen) if (namebuf) { SDL20_strlcpy(namebuf, name, maxlen); return namebuf; - } else { - return name; } + return name; } return NULL; } @@ -3337,7 +3334,8 @@ Keysym20to12(const SDL_Keycode keysym20) * and so does the Latin-1 range (128-255) */ if (keysym20 == SDLK_PAUSE) { return SDLK12_PAUSE; - } else if (keysym20 == SDLK_CLEAR) { + } + if (keysym20 == SDLK_CLEAR) { return SDLK12_CLEAR; } return (SDL12Key) keysym20; @@ -4861,7 +4859,8 @@ Surface20to12(SDL_Surface *surface20) if (!surface20) { return NULL; - } else if (surface20->pitch > 65535) { + } + if (surface20->pitch > 65535) { SDL20_SetError("Pitch is too large"); /* can't fit to 16-bits */ return NULL; } @@ -5281,7 +5280,8 @@ SDL_ListModes(const SDL12_PixelFormat *format12, Uint32 flags) VideoModeList *modes = &VideoModes[i]; if (SDL_BITSPERPIXEL(modes->format) == bpp) { return modes->modes12; - } else if (SDL_BITSPERPIXEL(modes->format) == 24 && bpp == 32) { + } + if (SDL_BITSPERPIXEL(modes->format) == 24 && bpp == 32) { best_modes = modes; } else if (SDL_BITSPERPIXEL(modes->format) > bpp) { if (!best_modes || SDL_BITSPERPIXEL(modes->format) > SDL_BITSPERPIXEL(best_modes->format)) { @@ -6401,9 +6401,11 @@ SDL_UpperBlit(SDL12_Surface *src12, SDL12_Rect *srcrect12, SDL12_Surface *dst12, if ((src12 == NULL) || (dst12 == NULL)) { return SDL20_SetError("SDL_UpperBlit: passed a NULL surface"); - } else if ((src12->pixels == NULL) || (dst12->pixels == NULL)) { + } + if ((src12->pixels == NULL) || (dst12->pixels == NULL)) { return SDL20_SetError("SDL_UpperBlit: passed a surface with NULL pixels"); - } else if (SaveDestAlpha(src12, dst12, &dstrect20, &dstalpha) < 0) { + } + if (SaveDestAlpha(src12, dst12, &dstrect20, &dstalpha) < 0) { return -1; } @@ -6848,9 +6850,11 @@ SDL_UpdateRects(SDL12_Surface *surface12, int numrects, SDL12_Rect *rects12) if (!renderer) { continue; - } else if (!rect20.w || !rect20.h) { + } + if (!rect20.w || !rect20.h) { continue; - } else if (SDL20_LockTexture(VideoTexture20, &rect20, &pixels, &pitch) < 0) { + } + if (SDL20_LockTexture(VideoTexture20, &rect20, &pixels, &pitch) < 0) { continue; /* oh well */ } @@ -7312,7 +7316,8 @@ SDL_GetWMInfo(SDL12_SysWMinfo *info12) if (info12->version.major > 1) { SDL20_SetError("Requested version is unsupported"); return 0; /* some programs only test against 0, not -1 */ - } else if (!SupportSysWM) { + } + if (!SupportSysWM) { SDL20_SetError("No SysWM support available"); return 0; /* some programs only test against 0, not -1 */ } @@ -7514,9 +7519,11 @@ SDL_DisplayYUVOverlay(SDL12_Overlay *overlay12, SDL12_Rect *dstrect12) if (!overlay12) { return SDL20_InvalidParamError("overlay"); - } else if (!dstrect12) { + } + if (!dstrect12) { return SDL20_InvalidParamError("dstrect"); - } else if (!(renderer = LockVideoRenderer())) { + } + if (!(renderer = LockVideoRenderer())) { return SDL20_SetError("No software screen surface available"); } @@ -7702,11 +7709,11 @@ SDL_GL_SetAttribute(SDL12_GLattr attr, int value) SwapInterval = value; return 0; } - else if (attr == SDL12_GL_MULTISAMPLESAMPLES) { + if (attr == SDL12_GL_MULTISAMPLESAMPLES) { OpenGLLogicalScalingSamples = value; return 0; } - else if (attr == SDL12_GL_MULTISAMPLEBUFFERS) { + if (attr == SDL12_GL_MULTISAMPLEBUFFERS) { return 0; } return SDL20_GL_SetAttribute((SDL_GLattr) attr, value); @@ -7725,11 +7732,11 @@ SDL_GL_GetAttribute(SDL12_GLattr attr, int* value) *value = SDL20_GL_GetSwapInterval(); return 0; } - else if (attr == SDL12_GL_MULTISAMPLESAMPLES) { + if (attr == SDL12_GL_MULTISAMPLESAMPLES) { *value = OpenGLLogicalScalingSamples; return 0; } - else if (attr == SDL12_GL_MULTISAMPLEBUFFERS) { + if (attr == SDL12_GL_MULTISAMPLEBUFFERS) { *value = (OpenGLLogicalScalingSamples) ? 1 : 0; return 0; } @@ -8855,15 +8862,20 @@ SDL_CDPlayTracks(SDL12_CD *cdrom, int start_track, int start_frame, int ntracks, { if ((cdrom = ValidCDDevice(cdrom)) == NULL) { return -1; - } else if (cdrom->status == SDL12_CD_TRAYEMPTY) { + } + if (cdrom->status == SDL12_CD_TRAYEMPTY) { return SDL20_SetError("Tray empty"); - } else if ((start_track < 0) || (start_track >= cdrom->numtracks)) { + } + if ((start_track < 0) || (start_track >= cdrom->numtracks)) { return SDL20_SetError("Invalid start track"); - } else if ((start_frame < 0) || (((Uint32) start_frame) >= cdrom->track[start_track].length)) { + } + if ((start_frame < 0) || (((Uint32) start_frame) >= cdrom->track[start_track].length)) { return SDL20_SetError("Invalid start frame"); - } else if ((ntracks < 0) || ((start_track + ntracks) >= cdrom->numtracks)) { + } + if ((ntracks < 0) || ((start_track + ntracks) >= cdrom->numtracks)) { return SDL20_SetError("Invalid number of tracks"); - } else if ((nframes < 0) || (((Uint32) nframes) >= cdrom->track[start_track + ntracks].length)) { + } + if ((nframes < 0) || (((Uint32) nframes) >= cdrom->track[start_track + ntracks].length)) { return SDL20_SetError("Invalid number of frames"); } @@ -8888,11 +8900,14 @@ SDL_CDPlay(SDL12_CD *cdrom, int start, int length) if ((cdrom = ValidCDDevice(cdrom)) == NULL) { return -1; - } else if (cdrom->status == SDL12_CD_TRAYEMPTY) { + } + if (cdrom->status == SDL12_CD_TRAYEMPTY) { return SDL20_SetError("Tray empty"); - } else if (start < 0) { + } + if (start < 0) { return SDL20_SetError("Invalid start"); - } else if (length < 0) { + } + if (length < 0) { return SDL20_SetError("Invalid length"); } @@ -8939,7 +8954,8 @@ SDL_CDPause(SDL12_CD *cdrom) { if ((cdrom = ValidCDDevice(cdrom)) == NULL) { return -1; - } else if (cdrom->status == SDL12_CD_TRAYEMPTY) { + } + if (cdrom->status == SDL12_CD_TRAYEMPTY) { return SDL20_SetError("Tray empty"); } @@ -8959,7 +8975,8 @@ SDL_CDResume(SDL12_CD *cdrom) { if ((cdrom = ValidCDDevice(cdrom)) == NULL) { return -1; - } else if (cdrom->status == SDL12_CD_TRAYEMPTY) { + } + if (cdrom->status == SDL12_CD_TRAYEMPTY) { return SDL20_SetError("Tray empty"); } From 510bc7e65d5e5fe290e6d416db14dba6e09d12f0 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sat, 4 Feb 2023 17:01:02 +0300 Subject: [PATCH 437/606] we have no business with DisableScreenSaver/EnableScreenSaver from SDL2 --- src/SDL20_syms.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/SDL20_syms.h b/src/SDL20_syms.h index 23a97a9ce..652a265d0 100644 --- a/src/SDL20_syms.h +++ b/src/SDL20_syms.h @@ -81,9 +81,6 @@ SDL20_SYM(int,GetDesktopDisplayMode,(int a, SDL_DisplayMode *b),(a,b),return) SDL20_SYM(int,GetCurrentDisplayMode,(int a, SDL_DisplayMode *b),(a,b),return) SDL20_SYM(int,GetWindowDisplayMode,(SDL_Window *a, SDL_DisplayMode *b),(a,b),return) -SDL20_SYM(void,EnableScreenSaver,(void),(),) -SDL20_SYM(void,DisableScreenSaver,(void),(),) - SDL20_SYM(SDL_Window *,CreateWindow,(const char *a, int b, int c, int d, int e, Uint32 f),(a,b,c,d,e,f),return) SDL20_SYM(SDL_Window *,CreateWindowFrom,(const void *a),(a),return) SDL20_SYM(void,DestroyWindow,(SDL_Window *a),(a),) @@ -382,7 +379,6 @@ OPENGL_SYM(Core,void,glTexSubImage2D,(GLenum a, GLint b, GLint c, GLint d, GLsiz OPENGL_SYM(Core,void,glVertex2i,(GLint a, GLint b),(a,b),) OPENGL_SYM(Core,void,glTexCoord2f,(GLfloat a, GLfloat b),(a,b),) - OPENGL_EXT(GL_ARB_framebuffer_object) OPENGL_SYM(GL_ARB_framebuffer_object,void,glBindRenderbuffer,(GLenum a, GLuint b),(a,b),) OPENGL_SYM(GL_ARB_framebuffer_object,void,glDeleteRenderbuffers,(GLsizei a, const GLuint *b),(a,b),) From 52b92eed0ba7cc556f911a6757eed7884d95f6df Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sat, 4 Feb 2023 17:01:02 +0300 Subject: [PATCH 438/606] we do not need to define SDL_BlitSurface as SDL_UpperBlit again. --- src/SDL12_compat.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index c9142bce6..7bcdfaae9 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -57,8 +57,6 @@ #undef snprintf #undef vsnprintf -#define SDL_BlitSurface SDL_UpperBlit - #ifdef __linux__ #include /* for readlink() */ #endif From ca3ce22f962be72dbd8bfc8541d120539d1fc889 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sat, 4 Feb 2023 18:56:10 +0300 Subject: [PATCH 439/606] SDL20_include_wrapper.h: sync with latest SDL2 headers. Before this , many exported SDL-1.2 procedures used to be accidentally prototyped by SDL2 headers.. After this, build attempts against SDL2 headers older than 2.0.10 will result in redefinition warnings for SDL_RWsize, SDL_RWseek, SDL_RWtell, SDL_RWread, SDL_RWwrite, SDL_RWclose, and SDL_LoadFile, but the result will be OK. --- src/SDL12_compat.c | 12 +- src/SDL20_include_wrapper.h | 4447 +++++++++++++++++++++++++++++++++-- 2 files changed, 4228 insertions(+), 231 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 7bcdfaae9..5b3a5db0a 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -97,9 +97,18 @@ extern "C" { #define DECLSPEC12 DECLSPEC FORCEALIGNATTR +/** Enable this to have warnings about wrong prototypes in SDL20_syms.h. + * It won't compile but it helps to make sure it's sync'ed with SDL2 headers. + */ +#if 0 +#define SDL20_SYM(rc,fn,params,args,ret) \ + typedef rc (SDLCALL *SDL20_##fn##_t) params; \ + static SDL20_##fn##_t SDL20_##fn = IGNORE_THIS_VERSION_OF_SDL_##fn; +#else #define SDL20_SYM(rc,fn,params,args,ret) \ typedef rc (SDLCALL *SDL20_##fn##_t) params; \ static SDL20_##fn##_t SDL20_##fn = NULL; +#endif #include "SDL20_syms.h" /* Things that _should_ be binary compatible pass right through... */ @@ -4566,8 +4575,7 @@ EventFilter20to12(void *data, SDL_Event *event20) } /* some programs rely on unicode values for these control characters */ - switch (PendingKeydownEvent.key.keysym.sym) - { + switch (PendingKeydownEvent.key.keysym.sym) { case SDLK12_BACKSPACE: FlushPendingKeydownEvent('\b'); break; diff --git a/src/SDL20_include_wrapper.h b/src/SDL20_include_wrapper.h index 3f8461ef0..b461e10e7 100644 --- a/src/SDL20_include_wrapper.h +++ b/src/SDL20_include_wrapper.h @@ -28,94 +28,873 @@ #ifndef _INCL_SDL20_INCLUDE_WRAPPER_H_ #define _INCL_SDL20_INCLUDE_WRAPPER_H_ -#define SDL_GetVersion IGNORE_THIS_VERSION_OF_SDL_GetVersion +#define SDL_SetError IGNORE_THIS_VERSION_OF_SDL_SetError #define SDL_Log IGNORE_THIS_VERSION_OF_SDL_Log +#define SDL_LogVerbose IGNORE_THIS_VERSION_OF_SDL_LogVerbose +#define SDL_LogDebug IGNORE_THIS_VERSION_OF_SDL_LogDebug +#define SDL_LogInfo IGNORE_THIS_VERSION_OF_SDL_LogInfo +#define SDL_LogWarn IGNORE_THIS_VERSION_OF_SDL_LogWarn +#define SDL_LogError IGNORE_THIS_VERSION_OF_SDL_LogError +#define SDL_LogCritical IGNORE_THIS_VERSION_OF_SDL_LogCritical +#define SDL_LogMessage IGNORE_THIS_VERSION_OF_SDL_LogMessage +#define SDL_sscanf IGNORE_THIS_VERSION_OF_SDL_sscanf +#define SDL_snprintf IGNORE_THIS_VERSION_OF_SDL_snprintf +#define SDL_CreateThread IGNORE_THIS_VERSION_OF_SDL_CreateThread +#define SDL_RWFromFP IGNORE_THIS_VERSION_OF_SDL_RWFromFP +#define SDL_RegisterApp IGNORE_THIS_VERSION_OF_SDL_RegisterApp +#define SDL_UnregisterApp IGNORE_THIS_VERSION_OF_SDL_UnregisterApp +#define SDL_Direct3D9GetAdapterIndex IGNORE_THIS_VERSION_OF_SDL_Direct3D9GetAdapterIndex +#define SDL_RenderGetD3D9Device IGNORE_THIS_VERSION_OF_SDL_RenderGetD3D9Device +#define SDL_iPhoneSetAnimationCallback IGNORE_THIS_VERSION_OF_SDL_iPhoneSetAnimationCallback +#define SDL_iPhoneSetEventPump IGNORE_THIS_VERSION_OF_SDL_iPhoneSetEventPump +#define SDL_AndroidGetJNIEnv IGNORE_THIS_VERSION_OF_SDL_AndroidGetJNIEnv +#define SDL_AndroidGetActivity IGNORE_THIS_VERSION_OF_SDL_AndroidGetActivity +#define SDL_AndroidGetInternalStoragePath IGNORE_THIS_VERSION_OF_SDL_AndroidGetInternalStoragePath +#define SDL_AndroidGetExternalStorageState IGNORE_THIS_VERSION_OF_SDL_AndroidGetExternalStorageState +#define SDL_AndroidGetExternalStoragePath IGNORE_THIS_VERSION_OF_SDL_AndroidGetExternalStoragePath +#define SDL_Init IGNORE_THIS_VERSION_OF_SDL_Init +#define SDL_InitSubSystem IGNORE_THIS_VERSION_OF_SDL_InitSubSystem +#define SDL_QuitSubSystem IGNORE_THIS_VERSION_OF_SDL_QuitSubSystem +#define SDL_WasInit IGNORE_THIS_VERSION_OF_SDL_WasInit +#define SDL_Quit IGNORE_THIS_VERSION_OF_SDL_Quit #define SDL_ReportAssertion IGNORE_THIS_VERSION_OF_SDL_ReportAssertion +#define SDL_SetAssertionHandler IGNORE_THIS_VERSION_OF_SDL_SetAssertionHandler +#define SDL_GetAssertionReport IGNORE_THIS_VERSION_OF_SDL_GetAssertionReport +#define SDL_ResetAssertionReport IGNORE_THIS_VERSION_OF_SDL_ResetAssertionReport +#define SDL_AtomicTryLock IGNORE_THIS_VERSION_OF_SDL_AtomicTryLock +#define SDL_AtomicLock IGNORE_THIS_VERSION_OF_SDL_AtomicLock +#define SDL_AtomicUnlock IGNORE_THIS_VERSION_OF_SDL_AtomicUnlock +#define SDL_AtomicCAS IGNORE_THIS_VERSION_OF_SDL_AtomicCAS +#define SDL_AtomicSet IGNORE_THIS_VERSION_OF_SDL_AtomicSet +#define SDL_AtomicGet IGNORE_THIS_VERSION_OF_SDL_AtomicGet +#define SDL_AtomicAdd IGNORE_THIS_VERSION_OF_SDL_AtomicAdd +#define SDL_AtomicCASPtr IGNORE_THIS_VERSION_OF_SDL_AtomicCASPtr +#define SDL_AtomicSetPtr IGNORE_THIS_VERSION_OF_SDL_AtomicSetPtr +#define SDL_AtomicGetPtr IGNORE_THIS_VERSION_OF_SDL_AtomicGetPtr +#define SDL_GetNumAudioDrivers IGNORE_THIS_VERSION_OF_SDL_GetNumAudioDrivers +#define SDL_GetAudioDriver IGNORE_THIS_VERSION_OF_SDL_GetAudioDriver +#define SDL_AudioInit IGNORE_THIS_VERSION_OF_SDL_AudioInit +#define SDL_AudioQuit IGNORE_THIS_VERSION_OF_SDL_AudioQuit +#define SDL_GetCurrentAudioDriver IGNORE_THIS_VERSION_OF_SDL_GetCurrentAudioDriver +#define SDL_OpenAudio IGNORE_THIS_VERSION_OF_SDL_OpenAudio +#define SDL_GetNumAudioDevices IGNORE_THIS_VERSION_OF_SDL_GetNumAudioDevices +#define SDL_GetAudioDeviceName IGNORE_THIS_VERSION_OF_SDL_GetAudioDeviceName +#define SDL_OpenAudioDevice IGNORE_THIS_VERSION_OF_SDL_OpenAudioDevice +#define SDL_GetAudioStatus IGNORE_THIS_VERSION_OF_SDL_GetAudioStatus +#define SDL_GetAudioDeviceStatus IGNORE_THIS_VERSION_OF_SDL_GetAudioDeviceStatus +#define SDL_PauseAudio IGNORE_THIS_VERSION_OF_SDL_PauseAudio +#define SDL_PauseAudioDevice IGNORE_THIS_VERSION_OF_SDL_PauseAudioDevice +#define SDL_LoadWAV_RW IGNORE_THIS_VERSION_OF_SDL_LoadWAV_RW +#define SDL_FreeWAV IGNORE_THIS_VERSION_OF_SDL_FreeWAV +#define SDL_BuildAudioCVT IGNORE_THIS_VERSION_OF_SDL_BuildAudioCVT +#define SDL_ConvertAudio IGNORE_THIS_VERSION_OF_SDL_ConvertAudio +#define SDL_MixAudio IGNORE_THIS_VERSION_OF_SDL_MixAudio +#define SDL_MixAudioFormat IGNORE_THIS_VERSION_OF_SDL_MixAudioFormat +#define SDL_LockAudio IGNORE_THIS_VERSION_OF_SDL_LockAudio +#define SDL_LockAudioDevice IGNORE_THIS_VERSION_OF_SDL_LockAudioDevice +#define SDL_UnlockAudio IGNORE_THIS_VERSION_OF_SDL_UnlockAudio +#define SDL_UnlockAudioDevice IGNORE_THIS_VERSION_OF_SDL_UnlockAudioDevice +#define SDL_CloseAudio IGNORE_THIS_VERSION_OF_SDL_CloseAudio +#define SDL_CloseAudioDevice IGNORE_THIS_VERSION_OF_SDL_CloseAudioDevice +#define SDL_SetClipboardText IGNORE_THIS_VERSION_OF_SDL_SetClipboardText +#define SDL_GetClipboardText IGNORE_THIS_VERSION_OF_SDL_GetClipboardText +#define SDL_HasClipboardText IGNORE_THIS_VERSION_OF_SDL_HasClipboardText +#define SDL_GetCPUCount IGNORE_THIS_VERSION_OF_SDL_GetCPUCount +#define SDL_GetCPUCacheLineSize IGNORE_THIS_VERSION_OF_SDL_GetCPUCacheLineSize +#define SDL_HasRDTSC IGNORE_THIS_VERSION_OF_SDL_HasRDTSC +#define SDL_HasAltiVec IGNORE_THIS_VERSION_OF_SDL_HasAltiVec +#define SDL_HasMMX IGNORE_THIS_VERSION_OF_SDL_HasMMX +#define SDL_Has3DNow IGNORE_THIS_VERSION_OF_SDL_Has3DNow +#define SDL_HasSSE IGNORE_THIS_VERSION_OF_SDL_HasSSE +#define SDL_HasSSE2 IGNORE_THIS_VERSION_OF_SDL_HasSSE2 +#define SDL_HasSSE3 IGNORE_THIS_VERSION_OF_SDL_HasSSE3 +#define SDL_HasSSE41 IGNORE_THIS_VERSION_OF_SDL_HasSSE41 +#define SDL_HasSSE42 IGNORE_THIS_VERSION_OF_SDL_HasSSE42 +#define SDL_GetSystemRAM IGNORE_THIS_VERSION_OF_SDL_GetSystemRAM +#define SDL_GetError IGNORE_THIS_VERSION_OF_SDL_GetError +#define SDL_ClearError IGNORE_THIS_VERSION_OF_SDL_ClearError #define SDL_Error IGNORE_THIS_VERSION_OF_SDL_Error -#define SDL_SetError IGNORE_THIS_VERSION_OF_SDL_SetError -#define SDL_PollEvent IGNORE_THIS_VERSION_OF_SDL_PollEvent -#define SDL_PushEvent IGNORE_THIS_VERSION_OF_SDL_PushEvent -#define SDL_EventState IGNORE_THIS_VERSION_OF_SDL_EventState +#define SDL_PumpEvents IGNORE_THIS_VERSION_OF_SDL_PumpEvents #define SDL_PeepEvents IGNORE_THIS_VERSION_OF_SDL_PeepEvents +#define SDL_HasEvent IGNORE_THIS_VERSION_OF_SDL_HasEvent +#define SDL_HasEvents IGNORE_THIS_VERSION_OF_SDL_HasEvents +#define SDL_FlushEvent IGNORE_THIS_VERSION_OF_SDL_FlushEvent +#define SDL_FlushEvents IGNORE_THIS_VERSION_OF_SDL_FlushEvents +#define SDL_PollEvent IGNORE_THIS_VERSION_OF_SDL_PollEvent #define SDL_WaitEvent IGNORE_THIS_VERSION_OF_SDL_WaitEvent +#define SDL_WaitEventTimeout IGNORE_THIS_VERSION_OF_SDL_WaitEventTimeout +#define SDL_PushEvent IGNORE_THIS_VERSION_OF_SDL_PushEvent #define SDL_SetEventFilter IGNORE_THIS_VERSION_OF_SDL_SetEventFilter #define SDL_GetEventFilter IGNORE_THIS_VERSION_OF_SDL_GetEventFilter -#define SDL_CreateRGBSurface IGNORE_THIS_VERSION_OF_SDL_CreateRGBSurface -#define SDL_CreateRGBSurfaceFrom IGNORE_THIS_VERSION_OF_SDL_CreateRGBSurfaceFrom -#define SDL_FreeSurface IGNORE_THIS_VERSION_OF_SDL_FreeSurface -#define SDL_SetClipRect IGNORE_THIS_VERSION_OF_SDL_SetClipRect -#define SDL_GetClipRect IGNORE_THIS_VERSION_OF_SDL_GetClipRect -#define SDL_FillRect IGNORE_THIS_VERSION_OF_SDL_FillRect -#define SDL_GetRGB IGNORE_THIS_VERSION_OF_SDL_GetRGB -#define SDL_GetRGBA IGNORE_THIS_VERSION_OF_SDL_GetRGBA -#define SDL_MapRGB IGNORE_THIS_VERSION_OF_SDL_MapRGB -#define SDL_MapRGBA IGNORE_THIS_VERSION_OF_SDL_MapRGBA +#define SDL_AddEventWatch IGNORE_THIS_VERSION_OF_SDL_AddEventWatch +#define SDL_DelEventWatch IGNORE_THIS_VERSION_OF_SDL_DelEventWatch +#define SDL_FilterEvents IGNORE_THIS_VERSION_OF_SDL_FilterEvents +#define SDL_EventState IGNORE_THIS_VERSION_OF_SDL_EventState +#define SDL_RegisterEvents IGNORE_THIS_VERSION_OF_SDL_RegisterEvents +#define SDL_GetBasePath IGNORE_THIS_VERSION_OF_SDL_GetBasePath +#define SDL_GetPrefPath IGNORE_THIS_VERSION_OF_SDL_GetPrefPath +#define SDL_GameControllerAddMapping IGNORE_THIS_VERSION_OF_SDL_GameControllerAddMapping +#define SDL_GameControllerMappingForGUID IGNORE_THIS_VERSION_OF_SDL_GameControllerMappingForGUID +#define SDL_GameControllerMapping IGNORE_THIS_VERSION_OF_SDL_GameControllerMapping +#define SDL_IsGameController IGNORE_THIS_VERSION_OF_SDL_IsGameController +#define SDL_GameControllerNameForIndex IGNORE_THIS_VERSION_OF_SDL_GameControllerNameForIndex +#define SDL_GameControllerOpen IGNORE_THIS_VERSION_OF_SDL_GameControllerOpen +#define SDL_GameControllerName IGNORE_THIS_VERSION_OF_SDL_GameControllerName +#define SDL_GameControllerGetAttached IGNORE_THIS_VERSION_OF_SDL_GameControllerGetAttached +#define SDL_GameControllerGetJoystick IGNORE_THIS_VERSION_OF_SDL_GameControllerGetJoystick +#define SDL_GameControllerEventState IGNORE_THIS_VERSION_OF_SDL_GameControllerEventState +#define SDL_GameControllerUpdate IGNORE_THIS_VERSION_OF_SDL_GameControllerUpdate +#define SDL_GameControllerGetAxisFromString IGNORE_THIS_VERSION_OF_SDL_GameControllerGetAxisFromString +#define SDL_GameControllerGetStringForAxis IGNORE_THIS_VERSION_OF_SDL_GameControllerGetStringForAxis +#define SDL_GameControllerGetBindForAxis IGNORE_THIS_VERSION_OF_SDL_GameControllerGetBindForAxis +#define SDL_GameControllerGetAxis IGNORE_THIS_VERSION_OF_SDL_GameControllerGetAxis +#define SDL_GameControllerGetButtonFromString IGNORE_THIS_VERSION_OF_SDL_GameControllerGetButtonFromString +#define SDL_GameControllerGetStringForButton IGNORE_THIS_VERSION_OF_SDL_GameControllerGetStringForButton +#define SDL_GameControllerGetBindForButton IGNORE_THIS_VERSION_OF_SDL_GameControllerGetBindForButton +#define SDL_GameControllerGetButton IGNORE_THIS_VERSION_OF_SDL_GameControllerGetButton +#define SDL_GameControllerClose IGNORE_THIS_VERSION_OF_SDL_GameControllerClose +#define SDL_RecordGesture IGNORE_THIS_VERSION_OF_SDL_RecordGesture +#define SDL_SaveAllDollarTemplates IGNORE_THIS_VERSION_OF_SDL_SaveAllDollarTemplates +#define SDL_SaveDollarTemplate IGNORE_THIS_VERSION_OF_SDL_SaveDollarTemplate +#define SDL_LoadDollarTemplates IGNORE_THIS_VERSION_OF_SDL_LoadDollarTemplates +#define SDL_NumHaptics IGNORE_THIS_VERSION_OF_SDL_NumHaptics +#define SDL_HapticName IGNORE_THIS_VERSION_OF_SDL_HapticName +#define SDL_HapticOpen IGNORE_THIS_VERSION_OF_SDL_HapticOpen +#define SDL_HapticOpened IGNORE_THIS_VERSION_OF_SDL_HapticOpened +#define SDL_HapticIndex IGNORE_THIS_VERSION_OF_SDL_HapticIndex +#define SDL_MouseIsHaptic IGNORE_THIS_VERSION_OF_SDL_MouseIsHaptic +#define SDL_HapticOpenFromMouse IGNORE_THIS_VERSION_OF_SDL_HapticOpenFromMouse +#define SDL_JoystickIsHaptic IGNORE_THIS_VERSION_OF_SDL_JoystickIsHaptic +#define SDL_HapticOpenFromJoystick IGNORE_THIS_VERSION_OF_SDL_HapticOpenFromJoystick +#define SDL_HapticClose IGNORE_THIS_VERSION_OF_SDL_HapticClose +#define SDL_HapticNumEffects IGNORE_THIS_VERSION_OF_SDL_HapticNumEffects +#define SDL_HapticNumEffectsPlaying IGNORE_THIS_VERSION_OF_SDL_HapticNumEffectsPlaying +#define SDL_HapticQuery IGNORE_THIS_VERSION_OF_SDL_HapticQuery +#define SDL_HapticNumAxes IGNORE_THIS_VERSION_OF_SDL_HapticNumAxes +#define SDL_HapticEffectSupported IGNORE_THIS_VERSION_OF_SDL_HapticEffectSupported +#define SDL_HapticNewEffect IGNORE_THIS_VERSION_OF_SDL_HapticNewEffect +#define SDL_HapticUpdateEffect IGNORE_THIS_VERSION_OF_SDL_HapticUpdateEffect +#define SDL_HapticRunEffect IGNORE_THIS_VERSION_OF_SDL_HapticRunEffect +#define SDL_HapticStopEffect IGNORE_THIS_VERSION_OF_SDL_HapticStopEffect +#define SDL_HapticDestroyEffect IGNORE_THIS_VERSION_OF_SDL_HapticDestroyEffect +#define SDL_HapticGetEffectStatus IGNORE_THIS_VERSION_OF_SDL_HapticGetEffectStatus +#define SDL_HapticSetGain IGNORE_THIS_VERSION_OF_SDL_HapticSetGain +#define SDL_HapticSetAutocenter IGNORE_THIS_VERSION_OF_SDL_HapticSetAutocenter +#define SDL_HapticPause IGNORE_THIS_VERSION_OF_SDL_HapticPause +#define SDL_HapticUnpause IGNORE_THIS_VERSION_OF_SDL_HapticUnpause +#define SDL_HapticStopAll IGNORE_THIS_VERSION_OF_SDL_HapticStopAll +#define SDL_HapticRumbleSupported IGNORE_THIS_VERSION_OF_SDL_HapticRumbleSupported +#define SDL_HapticRumbleInit IGNORE_THIS_VERSION_OF_SDL_HapticRumbleInit +#define SDL_HapticRumblePlay IGNORE_THIS_VERSION_OF_SDL_HapticRumblePlay +#define SDL_HapticRumbleStop IGNORE_THIS_VERSION_OF_SDL_HapticRumbleStop +#define SDL_SetHintWithPriority IGNORE_THIS_VERSION_OF_SDL_SetHintWithPriority +#define SDL_SetHint IGNORE_THIS_VERSION_OF_SDL_SetHint +#define SDL_GetHint IGNORE_THIS_VERSION_OF_SDL_GetHint +#define SDL_AddHintCallback IGNORE_THIS_VERSION_OF_SDL_AddHintCallback +#define SDL_DelHintCallback IGNORE_THIS_VERSION_OF_SDL_DelHintCallback +#define SDL_ClearHints IGNORE_THIS_VERSION_OF_SDL_ClearHints +#define SDL_NumJoysticks IGNORE_THIS_VERSION_OF_SDL_NumJoysticks +#define SDL_JoystickNameForIndex IGNORE_THIS_VERSION_OF_SDL_JoystickNameForIndex +#define SDL_JoystickOpen IGNORE_THIS_VERSION_OF_SDL_JoystickOpen +#define SDL_JoystickName IGNORE_THIS_VERSION_OF_SDL_JoystickName +#define SDL_JoystickGetDeviceGUID IGNORE_THIS_VERSION_OF_SDL_JoystickGetDeviceGUID +#define SDL_JoystickGetGUID IGNORE_THIS_VERSION_OF_SDL_JoystickGetGUID +#define SDL_JoystickGetGUIDString IGNORE_THIS_VERSION_OF_SDL_JoystickGetGUIDString +#define SDL_JoystickGetGUIDFromString IGNORE_THIS_VERSION_OF_SDL_JoystickGetGUIDFromString +#define SDL_JoystickGetAttached IGNORE_THIS_VERSION_OF_SDL_JoystickGetAttached +#define SDL_JoystickInstanceID IGNORE_THIS_VERSION_OF_SDL_JoystickInstanceID +#define SDL_JoystickNumAxes IGNORE_THIS_VERSION_OF_SDL_JoystickNumAxes +#define SDL_JoystickNumBalls IGNORE_THIS_VERSION_OF_SDL_JoystickNumBalls +#define SDL_JoystickNumHats IGNORE_THIS_VERSION_OF_SDL_JoystickNumHats +#define SDL_JoystickNumButtons IGNORE_THIS_VERSION_OF_SDL_JoystickNumButtons +#define SDL_JoystickUpdate IGNORE_THIS_VERSION_OF_SDL_JoystickUpdate +#define SDL_JoystickEventState IGNORE_THIS_VERSION_OF_SDL_JoystickEventState +#define SDL_JoystickGetAxis IGNORE_THIS_VERSION_OF_SDL_JoystickGetAxis +#define SDL_JoystickGetHat IGNORE_THIS_VERSION_OF_SDL_JoystickGetHat +#define SDL_JoystickGetBall IGNORE_THIS_VERSION_OF_SDL_JoystickGetBall +#define SDL_JoystickGetButton IGNORE_THIS_VERSION_OF_SDL_JoystickGetButton +#define SDL_JoystickClose IGNORE_THIS_VERSION_OF_SDL_JoystickClose +#define SDL_GetKeyboardFocus IGNORE_THIS_VERSION_OF_SDL_GetKeyboardFocus +#define SDL_GetKeyboardState IGNORE_THIS_VERSION_OF_SDL_GetKeyboardState +#define SDL_GetModState IGNORE_THIS_VERSION_OF_SDL_GetModState +#define SDL_SetModState IGNORE_THIS_VERSION_OF_SDL_SetModState +#define SDL_GetKeyFromScancode IGNORE_THIS_VERSION_OF_SDL_GetKeyFromScancode +#define SDL_GetScancodeFromKey IGNORE_THIS_VERSION_OF_SDL_GetScancodeFromKey +#define SDL_GetScancodeName IGNORE_THIS_VERSION_OF_SDL_GetScancodeName +#define SDL_GetScancodeFromName IGNORE_THIS_VERSION_OF_SDL_GetScancodeFromName +#define SDL_GetKeyName IGNORE_THIS_VERSION_OF_SDL_GetKeyName +#define SDL_GetKeyFromName IGNORE_THIS_VERSION_OF_SDL_GetKeyFromName +#define SDL_StartTextInput IGNORE_THIS_VERSION_OF_SDL_StartTextInput +#define SDL_IsTextInputActive IGNORE_THIS_VERSION_OF_SDL_IsTextInputActive +#define SDL_StopTextInput IGNORE_THIS_VERSION_OF_SDL_StopTextInput +#define SDL_SetTextInputRect IGNORE_THIS_VERSION_OF_SDL_SetTextInputRect +#define SDL_HasScreenKeyboardSupport IGNORE_THIS_VERSION_OF_SDL_HasScreenKeyboardSupport +#define SDL_IsScreenKeyboardShown IGNORE_THIS_VERSION_OF_SDL_IsScreenKeyboardShown +#define SDL_LoadObject IGNORE_THIS_VERSION_OF_SDL_LoadObject +#define SDL_LoadFunction IGNORE_THIS_VERSION_OF_SDL_LoadFunction +#define SDL_UnloadObject IGNORE_THIS_VERSION_OF_SDL_UnloadObject +#define SDL_LogSetAllPriority IGNORE_THIS_VERSION_OF_SDL_LogSetAllPriority +#define SDL_LogSetPriority IGNORE_THIS_VERSION_OF_SDL_LogSetPriority +#define SDL_LogGetPriority IGNORE_THIS_VERSION_OF_SDL_LogGetPriority +#define SDL_LogResetPriorities IGNORE_THIS_VERSION_OF_SDL_LogResetPriorities +#define SDL_LogMessageV IGNORE_THIS_VERSION_OF_SDL_LogMessageV +#define SDL_LogGetOutputFunction IGNORE_THIS_VERSION_OF_SDL_LogGetOutputFunction +#define SDL_LogSetOutputFunction IGNORE_THIS_VERSION_OF_SDL_LogSetOutputFunction +#define SDL_SetMainReady IGNORE_THIS_VERSION_OF_SDL_SetMainReady +#define SDL_ShowMessageBox IGNORE_THIS_VERSION_OF_SDL_ShowMessageBox +#define SDL_ShowSimpleMessageBox IGNORE_THIS_VERSION_OF_SDL_ShowSimpleMessageBox +#define SDL_GetMouseFocus IGNORE_THIS_VERSION_OF_SDL_GetMouseFocus +#define SDL_GetMouseState IGNORE_THIS_VERSION_OF_SDL_GetMouseState +#define SDL_GetRelativeMouseState IGNORE_THIS_VERSION_OF_SDL_GetRelativeMouseState +#define SDL_WarpMouseInWindow IGNORE_THIS_VERSION_OF_SDL_WarpMouseInWindow +#define SDL_SetRelativeMouseMode IGNORE_THIS_VERSION_OF_SDL_SetRelativeMouseMode +#define SDL_GetRelativeMouseMode IGNORE_THIS_VERSION_OF_SDL_GetRelativeMouseMode #define SDL_CreateCursor IGNORE_THIS_VERSION_OF_SDL_CreateCursor +#define SDL_CreateColorCursor IGNORE_THIS_VERSION_OF_SDL_CreateColorCursor +#define SDL_CreateSystemCursor IGNORE_THIS_VERSION_OF_SDL_CreateSystemCursor #define SDL_SetCursor IGNORE_THIS_VERSION_OF_SDL_SetCursor #define SDL_GetCursor IGNORE_THIS_VERSION_OF_SDL_GetCursor +#define SDL_GetDefaultCursor IGNORE_THIS_VERSION_OF_SDL_GetDefaultCursor #define SDL_FreeCursor IGNORE_THIS_VERSION_OF_SDL_FreeCursor -#define SDL_UpdateRect IGNORE_THIS_VERSION_OF_SDL_UpdateRect -#define SDL_UpdateRects IGNORE_THIS_VERSION_OF_SDL_UpdateRects -#define SDL_GetMouseState IGNORE_THIS_VERSION_OF_SDL_GetMouseState -#define SDL_GetRelativeMouseState IGNORE_THIS_VERSION_OF_SDL_GetRelativeMouseState -#define SDL_GL_SetAttribute IGNORE_THIS_VERSION_OF_SDL_GL_SetAttribute -#define SDL_GL_GetAttribute IGNORE_THIS_VERSION_OF_SDL_GL_GetAttribute -#define SDL_CreateThread IGNORE_THIS_VERSION_OF_SDL_CreateThread -#define SDL_AddTimer IGNORE_THIS_VERSION_OF_SDL_AddTimer -#define SDL_RemoveTimer IGNORE_THIS_VERSION_OF_SDL_RemoveTimer -#define SDL_AllocRW IGNORE_THIS_VERSION_OF_SDL_AllocRW -#define SDL_FreeRW IGNORE_THIS_VERSION_OF_SDL_FreeRW +#define SDL_ShowCursor IGNORE_THIS_VERSION_OF_SDL_ShowCursor +#define SDL_CreateMutex IGNORE_THIS_VERSION_OF_SDL_CreateMutex +#define SDL_LockMutex IGNORE_THIS_VERSION_OF_SDL_LockMutex +#define SDL_TryLockMutex IGNORE_THIS_VERSION_OF_SDL_TryLockMutex +#define SDL_UnlockMutex IGNORE_THIS_VERSION_OF_SDL_UnlockMutex +#define SDL_DestroyMutex IGNORE_THIS_VERSION_OF_SDL_DestroyMutex +#define SDL_CreateSemaphore IGNORE_THIS_VERSION_OF_SDL_CreateSemaphore +#define SDL_DestroySemaphore IGNORE_THIS_VERSION_OF_SDL_DestroySemaphore +#define SDL_SemWait IGNORE_THIS_VERSION_OF_SDL_SemWait +#define SDL_SemTryWait IGNORE_THIS_VERSION_OF_SDL_SemTryWait +#define SDL_SemWaitTimeout IGNORE_THIS_VERSION_OF_SDL_SemWaitTimeout +#define SDL_SemPost IGNORE_THIS_VERSION_OF_SDL_SemPost +#define SDL_SemValue IGNORE_THIS_VERSION_OF_SDL_SemValue +#define SDL_CreateCond IGNORE_THIS_VERSION_OF_SDL_CreateCond +#define SDL_DestroyCond IGNORE_THIS_VERSION_OF_SDL_DestroyCond +#define SDL_CondSignal IGNORE_THIS_VERSION_OF_SDL_CondSignal +#define SDL_CondBroadcast IGNORE_THIS_VERSION_OF_SDL_CondBroadcast +#define SDL_CondWait IGNORE_THIS_VERSION_OF_SDL_CondWait +#define SDL_CondWaitTimeout IGNORE_THIS_VERSION_OF_SDL_CondWaitTimeout +#define SDL_GetPixelFormatName IGNORE_THIS_VERSION_OF_SDL_GetPixelFormatName +#define SDL_PixelFormatEnumToMasks IGNORE_THIS_VERSION_OF_SDL_PixelFormatEnumToMasks +#define SDL_MasksToPixelFormatEnum IGNORE_THIS_VERSION_OF_SDL_MasksToPixelFormatEnum +#define SDL_AllocFormat IGNORE_THIS_VERSION_OF_SDL_AllocFormat +#define SDL_FreeFormat IGNORE_THIS_VERSION_OF_SDL_FreeFormat +#define SDL_AllocPalette IGNORE_THIS_VERSION_OF_SDL_AllocPalette +#define SDL_SetPixelFormatPalette IGNORE_THIS_VERSION_OF_SDL_SetPixelFormatPalette +#define SDL_SetPaletteColors IGNORE_THIS_VERSION_OF_SDL_SetPaletteColors +#define SDL_FreePalette IGNORE_THIS_VERSION_OF_SDL_FreePalette +#define SDL_MapRGB IGNORE_THIS_VERSION_OF_SDL_MapRGB +#define SDL_MapRGBA IGNORE_THIS_VERSION_OF_SDL_MapRGBA +#define SDL_GetRGB IGNORE_THIS_VERSION_OF_SDL_GetRGB +#define SDL_GetRGBA IGNORE_THIS_VERSION_OF_SDL_GetRGBA +#define SDL_CalculateGammaRamp IGNORE_THIS_VERSION_OF_SDL_CalculateGammaRamp +#define SDL_GetPlatform IGNORE_THIS_VERSION_OF_SDL_GetPlatform +#define SDL_GetPowerInfo IGNORE_THIS_VERSION_OF_SDL_GetPowerInfo +#define SDL_HasIntersection IGNORE_THIS_VERSION_OF_SDL_HasIntersection +#define SDL_IntersectRect IGNORE_THIS_VERSION_OF_SDL_IntersectRect +#define SDL_UnionRect IGNORE_THIS_VERSION_OF_SDL_UnionRect +#define SDL_EnclosePoints IGNORE_THIS_VERSION_OF_SDL_EnclosePoints +#define SDL_IntersectRectAndLine IGNORE_THIS_VERSION_OF_SDL_IntersectRectAndLine +#define SDL_GetNumRenderDrivers IGNORE_THIS_VERSION_OF_SDL_GetNumRenderDrivers +#define SDL_GetRenderDriverInfo IGNORE_THIS_VERSION_OF_SDL_GetRenderDriverInfo +#define SDL_CreateWindowAndRenderer IGNORE_THIS_VERSION_OF_SDL_CreateWindowAndRenderer +#define SDL_CreateRenderer IGNORE_THIS_VERSION_OF_SDL_CreateRenderer +#define SDL_CreateSoftwareRenderer IGNORE_THIS_VERSION_OF_SDL_CreateSoftwareRenderer +#define SDL_GetRenderer IGNORE_THIS_VERSION_OF_SDL_GetRenderer +#define SDL_GetRendererInfo IGNORE_THIS_VERSION_OF_SDL_GetRendererInfo +#define SDL_GetRendererOutputSize IGNORE_THIS_VERSION_OF_SDL_GetRendererOutputSize +#define SDL_CreateTexture IGNORE_THIS_VERSION_OF_SDL_CreateTexture +#define SDL_CreateTextureFromSurface IGNORE_THIS_VERSION_OF_SDL_CreateTextureFromSurface +#define SDL_QueryTexture IGNORE_THIS_VERSION_OF_SDL_QueryTexture +#define SDL_SetTextureColorMod IGNORE_THIS_VERSION_OF_SDL_SetTextureColorMod +#define SDL_GetTextureColorMod IGNORE_THIS_VERSION_OF_SDL_GetTextureColorMod +#define SDL_SetTextureAlphaMod IGNORE_THIS_VERSION_OF_SDL_SetTextureAlphaMod +#define SDL_GetTextureAlphaMod IGNORE_THIS_VERSION_OF_SDL_GetTextureAlphaMod +#define SDL_SetTextureBlendMode IGNORE_THIS_VERSION_OF_SDL_SetTextureBlendMode +#define SDL_GetTextureBlendMode IGNORE_THIS_VERSION_OF_SDL_GetTextureBlendMode +#define SDL_UpdateTexture IGNORE_THIS_VERSION_OF_SDL_UpdateTexture +#define SDL_UpdateYUVTexture IGNORE_THIS_VERSION_OF_SDL_UpdateYUVTexture +#define SDL_LockTexture IGNORE_THIS_VERSION_OF_SDL_LockTexture +#define SDL_UnlockTexture IGNORE_THIS_VERSION_OF_SDL_UnlockTexture +#define SDL_RenderTargetSupported IGNORE_THIS_VERSION_OF_SDL_RenderTargetSupported +#define SDL_SetRenderTarget IGNORE_THIS_VERSION_OF_SDL_SetRenderTarget +#define SDL_GetRenderTarget IGNORE_THIS_VERSION_OF_SDL_GetRenderTarget +#define SDL_RenderSetLogicalSize IGNORE_THIS_VERSION_OF_SDL_RenderSetLogicalSize +#define SDL_RenderGetLogicalSize IGNORE_THIS_VERSION_OF_SDL_RenderGetLogicalSize +#define SDL_RenderSetViewport IGNORE_THIS_VERSION_OF_SDL_RenderSetViewport +#define SDL_RenderGetViewport IGNORE_THIS_VERSION_OF_SDL_RenderGetViewport +#define SDL_RenderSetClipRect IGNORE_THIS_VERSION_OF_SDL_RenderSetClipRect +#define SDL_RenderGetClipRect IGNORE_THIS_VERSION_OF_SDL_RenderGetClipRect +#define SDL_RenderSetScale IGNORE_THIS_VERSION_OF_SDL_RenderSetScale +#define SDL_RenderGetScale IGNORE_THIS_VERSION_OF_SDL_RenderGetScale +#define SDL_SetRenderDrawColor IGNORE_THIS_VERSION_OF_SDL_SetRenderDrawColor +#define SDL_GetRenderDrawColor IGNORE_THIS_VERSION_OF_SDL_GetRenderDrawColor +#define SDL_SetRenderDrawBlendMode IGNORE_THIS_VERSION_OF_SDL_SetRenderDrawBlendMode +#define SDL_GetRenderDrawBlendMode IGNORE_THIS_VERSION_OF_SDL_GetRenderDrawBlendMode +#define SDL_RenderClear IGNORE_THIS_VERSION_OF_SDL_RenderClear +#define SDL_RenderDrawPoint IGNORE_THIS_VERSION_OF_SDL_RenderDrawPoint +#define SDL_RenderDrawPoints IGNORE_THIS_VERSION_OF_SDL_RenderDrawPoints +#define SDL_RenderDrawLine IGNORE_THIS_VERSION_OF_SDL_RenderDrawLine +#define SDL_RenderDrawLines IGNORE_THIS_VERSION_OF_SDL_RenderDrawLines +#define SDL_RenderDrawRect IGNORE_THIS_VERSION_OF_SDL_RenderDrawRect +#define SDL_RenderDrawRects IGNORE_THIS_VERSION_OF_SDL_RenderDrawRects +#define SDL_RenderFillRect IGNORE_THIS_VERSION_OF_SDL_RenderFillRect +#define SDL_RenderFillRects IGNORE_THIS_VERSION_OF_SDL_RenderFillRects +#define SDL_RenderCopy IGNORE_THIS_VERSION_OF_SDL_RenderCopy +#define SDL_RenderCopyEx IGNORE_THIS_VERSION_OF_SDL_RenderCopyEx +#define SDL_RenderReadPixels IGNORE_THIS_VERSION_OF_SDL_RenderReadPixels +#define SDL_RenderPresent IGNORE_THIS_VERSION_OF_SDL_RenderPresent +#define SDL_DestroyTexture IGNORE_THIS_VERSION_OF_SDL_DestroyTexture +#define SDL_DestroyRenderer IGNORE_THIS_VERSION_OF_SDL_DestroyRenderer +#define SDL_GL_BindTexture IGNORE_THIS_VERSION_OF_SDL_GL_BindTexture +#define SDL_GL_UnbindTexture IGNORE_THIS_VERSION_OF_SDL_GL_UnbindTexture #define SDL_RWFromFile IGNORE_THIS_VERSION_OF_SDL_RWFromFile -#define SDL_RWFromFP IGNORE_THIS_VERSION_OF_SDL_RWFromFP #define SDL_RWFromMem IGNORE_THIS_VERSION_OF_SDL_RWFromMem #define SDL_RWFromConstMem IGNORE_THIS_VERSION_OF_SDL_RWFromConstMem +#define SDL_AllocRW IGNORE_THIS_VERSION_OF_SDL_AllocRW +#define SDL_FreeRW IGNORE_THIS_VERSION_OF_SDL_FreeRW +#define SDL_ReadU8 IGNORE_THIS_VERSION_OF_SDL_ReadU8 #define SDL_ReadLE16 IGNORE_THIS_VERSION_OF_SDL_ReadLE16 #define SDL_ReadBE16 IGNORE_THIS_VERSION_OF_SDL_ReadBE16 #define SDL_ReadLE32 IGNORE_THIS_VERSION_OF_SDL_ReadLE32 #define SDL_ReadBE32 IGNORE_THIS_VERSION_OF_SDL_ReadBE32 #define SDL_ReadLE64 IGNORE_THIS_VERSION_OF_SDL_ReadLE64 #define SDL_ReadBE64 IGNORE_THIS_VERSION_OF_SDL_ReadBE64 +#define SDL_WriteU8 IGNORE_THIS_VERSION_OF_SDL_WriteU8 #define SDL_WriteLE16 IGNORE_THIS_VERSION_OF_SDL_WriteLE16 #define SDL_WriteBE16 IGNORE_THIS_VERSION_OF_SDL_WriteBE16 #define SDL_WriteLE32 IGNORE_THIS_VERSION_OF_SDL_WriteLE32 #define SDL_WriteBE32 IGNORE_THIS_VERSION_OF_SDL_WriteBE32 #define SDL_WriteLE64 IGNORE_THIS_VERSION_OF_SDL_WriteLE64 #define SDL_WriteBE64 IGNORE_THIS_VERSION_OF_SDL_WriteBE64 -#define SDL_GetThreadID IGNORE_THIS_VERSION_OF_SDL_GetThreadID -#define SDL_ThreadID IGNORE_THIS_VERSION_OF_SDL_ThreadID -#define SDL_NumJoysticks IGNORE_THIS_VERSION_OF_SDL_NumJoysticks -#define SDL_JoystickNumAxes IGNORE_THIS_VERSION_OF_SDL_JoystickNumAxes -#define SDL_JoystickNumBalls IGNORE_THIS_VERSION_OF_SDL_JoystickNumBalls -#define SDL_JoystickNumHats IGNORE_THIS_VERSION_OF_SDL_JoystickNumHats -#define SDL_JoystickNumButtons IGNORE_THIS_VERSION_OF_SDL_JoystickNumButtons -#define SDL_JoystickUpdate IGNORE_THIS_VERSION_OF_SDL_JoystickUpdate -#define SDL_JoystickEventState IGNORE_THIS_VERSION_OF_SDL_JoystickEventState -#define SDL_JoystickGetAxis IGNORE_THIS_VERSION_OF_SDL_JoystickGetAxis -#define SDL_JoystickGetHat IGNORE_THIS_VERSION_OF_SDL_JoystickGetHat -#define SDL_JoystickGetBall IGNORE_THIS_VERSION_OF_SDL_JoystickGetBall -#define SDL_JoystickGetButton IGNORE_THIS_VERSION_OF_SDL_JoystickGetButton -#define SDL_JoystickOpen IGNORE_THIS_VERSION_OF_SDL_JoystickOpen -#define SDL_JoystickClose IGNORE_THIS_VERSION_OF_SDL_JoystickClose -#define SDL_JoystickName IGNORE_THIS_VERSION_OF_SDL_JoystickName -#define SDL_JoystickIndex IGNORE_THIS_VERSION_OF_SDL_JoystickIndex -#define SDL_JoystickOpened IGNORE_THIS_VERSION_OF_SDL_JoystickOpened +#define SDL_CreateShapedWindow IGNORE_THIS_VERSION_OF_SDL_CreateShapedWindow +#define SDL_IsShapedWindow IGNORE_THIS_VERSION_OF_SDL_IsShapedWindow +#define SDL_SetWindowShape IGNORE_THIS_VERSION_OF_SDL_SetWindowShape +#define SDL_GetShapedWindowMode IGNORE_THIS_VERSION_OF_SDL_GetShapedWindowMode +#define SDL_malloc IGNORE_THIS_VERSION_OF_SDL_malloc +#define SDL_calloc IGNORE_THIS_VERSION_OF_SDL_calloc +#define SDL_realloc IGNORE_THIS_VERSION_OF_SDL_realloc +#define SDL_free IGNORE_THIS_VERSION_OF_SDL_free +#define SDL_getenv IGNORE_THIS_VERSION_OF_SDL_getenv +#define SDL_setenv IGNORE_THIS_VERSION_OF_SDL_setenv +#define SDL_qsort IGNORE_THIS_VERSION_OF_SDL_qsort +#define SDL_abs IGNORE_THIS_VERSION_OF_SDL_abs +#define SDL_isdigit IGNORE_THIS_VERSION_OF_SDL_isdigit +#define SDL_isspace IGNORE_THIS_VERSION_OF_SDL_isspace +#define SDL_toupper IGNORE_THIS_VERSION_OF_SDL_toupper +#define SDL_tolower IGNORE_THIS_VERSION_OF_SDL_tolower +#define SDL_memset IGNORE_THIS_VERSION_OF_SDL_memset +#define SDL_memcpy IGNORE_THIS_VERSION_OF_SDL_memcpy +#define SDL_memmove IGNORE_THIS_VERSION_OF_SDL_memmove +#define SDL_memcmp IGNORE_THIS_VERSION_OF_SDL_memcmp +#define SDL_wcslen IGNORE_THIS_VERSION_OF_SDL_wcslen +#define SDL_wcslcpy IGNORE_THIS_VERSION_OF_SDL_wcslcpy +#define SDL_wcslcat IGNORE_THIS_VERSION_OF_SDL_wcslcat +#define SDL_strlen IGNORE_THIS_VERSION_OF_SDL_strlen +#define SDL_strlcpy IGNORE_THIS_VERSION_OF_SDL_strlcpy +#define SDL_utf8strlcpy IGNORE_THIS_VERSION_OF_SDL_utf8strlcpy +#define SDL_strlcat IGNORE_THIS_VERSION_OF_SDL_strlcat +#define SDL_strdup IGNORE_THIS_VERSION_OF_SDL_strdup +#define SDL_strrev IGNORE_THIS_VERSION_OF_SDL_strrev +#define SDL_strupr IGNORE_THIS_VERSION_OF_SDL_strupr +#define SDL_strlwr IGNORE_THIS_VERSION_OF_SDL_strlwr +#define SDL_strchr IGNORE_THIS_VERSION_OF_SDL_strchr +#define SDL_strrchr IGNORE_THIS_VERSION_OF_SDL_strrchr +#define SDL_strstr IGNORE_THIS_VERSION_OF_SDL_strstr +#define SDL_itoa IGNORE_THIS_VERSION_OF_SDL_itoa +#define SDL_uitoa IGNORE_THIS_VERSION_OF_SDL_uitoa +#define SDL_ltoa IGNORE_THIS_VERSION_OF_SDL_ltoa +#define SDL_ultoa IGNORE_THIS_VERSION_OF_SDL_ultoa +#define SDL_lltoa IGNORE_THIS_VERSION_OF_SDL_lltoa +#define SDL_ulltoa IGNORE_THIS_VERSION_OF_SDL_ulltoa +#define SDL_atoi IGNORE_THIS_VERSION_OF_SDL_atoi +#define SDL_atof IGNORE_THIS_VERSION_OF_SDL_atof +#define SDL_strtol IGNORE_THIS_VERSION_OF_SDL_strtol +#define SDL_strtoul IGNORE_THIS_VERSION_OF_SDL_strtoul +#define SDL_strtoll IGNORE_THIS_VERSION_OF_SDL_strtoll +#define SDL_strtoull IGNORE_THIS_VERSION_OF_SDL_strtoull +#define SDL_strtod IGNORE_THIS_VERSION_OF_SDL_strtod +#define SDL_strcmp IGNORE_THIS_VERSION_OF_SDL_strcmp +#define SDL_strncmp IGNORE_THIS_VERSION_OF_SDL_strncmp +#define SDL_strcasecmp IGNORE_THIS_VERSION_OF_SDL_strcasecmp +#define SDL_strncasecmp IGNORE_THIS_VERSION_OF_SDL_strncasecmp +#define SDL_vsnprintf IGNORE_THIS_VERSION_OF_SDL_vsnprintf +#define SDL_acos IGNORE_THIS_VERSION_OF_SDL_acos +#define SDL_asin IGNORE_THIS_VERSION_OF_SDL_asin +#define SDL_atan IGNORE_THIS_VERSION_OF_SDL_atan +#define SDL_atan2 IGNORE_THIS_VERSION_OF_SDL_atan2 +#define SDL_ceil IGNORE_THIS_VERSION_OF_SDL_ceil +#define SDL_copysign IGNORE_THIS_VERSION_OF_SDL_copysign +#define SDL_cos IGNORE_THIS_VERSION_OF_SDL_cos +#define SDL_cosf IGNORE_THIS_VERSION_OF_SDL_cosf +#define SDL_fabs IGNORE_THIS_VERSION_OF_SDL_fabs +#define SDL_floor IGNORE_THIS_VERSION_OF_SDL_floor +#define SDL_log IGNORE_THIS_VERSION_OF_SDL_log +#define SDL_pow IGNORE_THIS_VERSION_OF_SDL_pow +#define SDL_scalbn IGNORE_THIS_VERSION_OF_SDL_scalbn +#define SDL_sin IGNORE_THIS_VERSION_OF_SDL_sin +#define SDL_sinf IGNORE_THIS_VERSION_OF_SDL_sinf +#define SDL_sqrt IGNORE_THIS_VERSION_OF_SDL_sqrt +#define SDL_iconv_open IGNORE_THIS_VERSION_OF_SDL_iconv_open +#define SDL_iconv_close IGNORE_THIS_VERSION_OF_SDL_iconv_close +#define SDL_iconv IGNORE_THIS_VERSION_OF_SDL_iconv +#define SDL_iconv_string IGNORE_THIS_VERSION_OF_SDL_iconv_string +#define SDL_CreateRGBSurface IGNORE_THIS_VERSION_OF_SDL_CreateRGBSurface +#define SDL_CreateRGBSurfaceFrom IGNORE_THIS_VERSION_OF_SDL_CreateRGBSurfaceFrom +#define SDL_FreeSurface IGNORE_THIS_VERSION_OF_SDL_FreeSurface +#define SDL_SetSurfacePalette IGNORE_THIS_VERSION_OF_SDL_SetSurfacePalette +#define SDL_LockSurface IGNORE_THIS_VERSION_OF_SDL_LockSurface +#define SDL_UnlockSurface IGNORE_THIS_VERSION_OF_SDL_UnlockSurface #define SDL_LoadBMP_RW IGNORE_THIS_VERSION_OF_SDL_LoadBMP_RW #define SDL_SaveBMP_RW IGNORE_THIS_VERSION_OF_SDL_SaveBMP_RW -#define SDL_LoadWAV_RW IGNORE_THIS_VERSION_OF_SDL_LoadWAV_RW +#define SDL_SetSurfaceRLE IGNORE_THIS_VERSION_OF_SDL_SetSurfaceRLE +#define SDL_SetColorKey IGNORE_THIS_VERSION_OF_SDL_SetColorKey +#define SDL_GetColorKey IGNORE_THIS_VERSION_OF_SDL_GetColorKey +#define SDL_SetSurfaceColorMod IGNORE_THIS_VERSION_OF_SDL_SetSurfaceColorMod +#define SDL_GetSurfaceColorMod IGNORE_THIS_VERSION_OF_SDL_GetSurfaceColorMod +#define SDL_SetSurfaceAlphaMod IGNORE_THIS_VERSION_OF_SDL_SetSurfaceAlphaMod +#define SDL_GetSurfaceAlphaMod IGNORE_THIS_VERSION_OF_SDL_GetSurfaceAlphaMod +#define SDL_SetSurfaceBlendMode IGNORE_THIS_VERSION_OF_SDL_SetSurfaceBlendMode +#define SDL_GetSurfaceBlendMode IGNORE_THIS_VERSION_OF_SDL_GetSurfaceBlendMode +#define SDL_SetClipRect IGNORE_THIS_VERSION_OF_SDL_SetClipRect +#define SDL_GetClipRect IGNORE_THIS_VERSION_OF_SDL_GetClipRect +#define SDL_ConvertSurface IGNORE_THIS_VERSION_OF_SDL_ConvertSurface +#define SDL_ConvertSurfaceFormat IGNORE_THIS_VERSION_OF_SDL_ConvertSurfaceFormat +#define SDL_ConvertPixels IGNORE_THIS_VERSION_OF_SDL_ConvertPixels +#define SDL_FillRect IGNORE_THIS_VERSION_OF_SDL_FillRect +#define SDL_FillRects IGNORE_THIS_VERSION_OF_SDL_FillRects #define SDL_UpperBlit IGNORE_THIS_VERSION_OF_SDL_UpperBlit #define SDL_LowerBlit IGNORE_THIS_VERSION_OF_SDL_LowerBlit #define SDL_SoftStretch IGNORE_THIS_VERSION_OF_SDL_SoftStretch -#define SDL_ConvertSurface IGNORE_THIS_VERSION_OF_SDL_ConvertSurface -#define SDL_SetColorKey IGNORE_THIS_VERSION_OF_SDL_SetColorKey -#define SDL_LockSurface IGNORE_THIS_VERSION_OF_SDL_LockSurface -#define SDL_UnlockSurface IGNORE_THIS_VERSION_OF_SDL_UnlockSurface -#define SDL_GetKeyName IGNORE_THIS_VERSION_OF_SDL_GetKeyName +#define SDL_UpperBlitScaled IGNORE_THIS_VERSION_OF_SDL_UpperBlitScaled +#define SDL_LowerBlitScaled IGNORE_THIS_VERSION_OF_SDL_LowerBlitScaled +#define SDL_GetWindowWMInfo IGNORE_THIS_VERSION_OF_SDL_GetWindowWMInfo +#define SDL_GetThreadName IGNORE_THIS_VERSION_OF_SDL_GetThreadName +#define SDL_ThreadID IGNORE_THIS_VERSION_OF_SDL_ThreadID +#define SDL_GetThreadID IGNORE_THIS_VERSION_OF_SDL_GetThreadID +#define SDL_SetThreadPriority IGNORE_THIS_VERSION_OF_SDL_SetThreadPriority +#define SDL_WaitThread IGNORE_THIS_VERSION_OF_SDL_WaitThread +#define SDL_DetachThread IGNORE_THIS_VERSION_OF_SDL_DetachThread +#define SDL_TLSCreate IGNORE_THIS_VERSION_OF_SDL_TLSCreate +#define SDL_TLSGet IGNORE_THIS_VERSION_OF_SDL_TLSGet +#define SDL_TLSSet IGNORE_THIS_VERSION_OF_SDL_TLSSet +#define SDL_GetTicks IGNORE_THIS_VERSION_OF_SDL_GetTicks +#define SDL_GetPerformanceCounter IGNORE_THIS_VERSION_OF_SDL_GetPerformanceCounter +#define SDL_GetPerformanceFrequency IGNORE_THIS_VERSION_OF_SDL_GetPerformanceFrequency +#define SDL_Delay IGNORE_THIS_VERSION_OF_SDL_Delay +#define SDL_AddTimer IGNORE_THIS_VERSION_OF_SDL_AddTimer +#define SDL_RemoveTimer IGNORE_THIS_VERSION_OF_SDL_RemoveTimer +#define SDL_GetNumTouchDevices IGNORE_THIS_VERSION_OF_SDL_GetNumTouchDevices +#define SDL_GetTouchDevice IGNORE_THIS_VERSION_OF_SDL_GetTouchDevice +#define SDL_GetNumTouchFingers IGNORE_THIS_VERSION_OF_SDL_GetNumTouchFingers +#define SDL_GetTouchFinger IGNORE_THIS_VERSION_OF_SDL_GetTouchFinger +#define SDL_GetVersion IGNORE_THIS_VERSION_OF_SDL_GetVersion +#define SDL_GetRevision IGNORE_THIS_VERSION_OF_SDL_GetRevision +#define SDL_GetRevisionNumber IGNORE_THIS_VERSION_OF_SDL_GetRevisionNumber +#define SDL_GetNumVideoDrivers IGNORE_THIS_VERSION_OF_SDL_GetNumVideoDrivers +#define SDL_GetVideoDriver IGNORE_THIS_VERSION_OF_SDL_GetVideoDriver #define SDL_VideoInit IGNORE_THIS_VERSION_OF_SDL_VideoInit -#define SDL_BuildAudioCVT IGNORE_THIS_VERSION_OF_SDL_BuildAudioCVT -#define SDL_ConvertAudio IGNORE_THIS_VERSION_OF_SDL_ConvertAudio -#define SDL_MixAudio IGNORE_THIS_VERSION_OF_SDL_MixAudio -#define SDL_RegisterApp IGNORE_THIS_VERSION_OF_SDL_RegisterApp -#define SDL_UnregisterApp IGNORE_THIS_VERSION_OF_SDL_UnregisterApp +#define SDL_VideoQuit IGNORE_THIS_VERSION_OF_SDL_VideoQuit +#define SDL_GetCurrentVideoDriver IGNORE_THIS_VERSION_OF_SDL_GetCurrentVideoDriver +#define SDL_GetNumVideoDisplays IGNORE_THIS_VERSION_OF_SDL_GetNumVideoDisplays +#define SDL_GetDisplayName IGNORE_THIS_VERSION_OF_SDL_GetDisplayName +#define SDL_GetDisplayBounds IGNORE_THIS_VERSION_OF_SDL_GetDisplayBounds +#define SDL_GetDisplayDPI IGNORE_THIS_VERSION_OF_SDL_GetDisplayDPI +#define SDL_GetNumDisplayModes IGNORE_THIS_VERSION_OF_SDL_GetNumDisplayModes +#define SDL_GetDisplayMode IGNORE_THIS_VERSION_OF_SDL_GetDisplayMode +#define SDL_GetDesktopDisplayMode IGNORE_THIS_VERSION_OF_SDL_GetDesktopDisplayMode +#define SDL_GetCurrentDisplayMode IGNORE_THIS_VERSION_OF_SDL_GetCurrentDisplayMode +#define SDL_GetClosestDisplayMode IGNORE_THIS_VERSION_OF_SDL_GetClosestDisplayMode +#define SDL_GetWindowDisplayIndex IGNORE_THIS_VERSION_OF_SDL_GetWindowDisplayIndex +#define SDL_SetWindowDisplayMode IGNORE_THIS_VERSION_OF_SDL_SetWindowDisplayMode +#define SDL_GetWindowDisplayMode IGNORE_THIS_VERSION_OF_SDL_GetWindowDisplayMode +#define SDL_GetWindowPixelFormat IGNORE_THIS_VERSION_OF_SDL_GetWindowPixelFormat +#define SDL_CreateWindow IGNORE_THIS_VERSION_OF_SDL_CreateWindow +#define SDL_CreateWindowFrom IGNORE_THIS_VERSION_OF_SDL_CreateWindowFrom +#define SDL_GetWindowID IGNORE_THIS_VERSION_OF_SDL_GetWindowID +#define SDL_GetWindowFromID IGNORE_THIS_VERSION_OF_SDL_GetWindowFromID +#define SDL_GetWindowFlags IGNORE_THIS_VERSION_OF_SDL_GetWindowFlags +#define SDL_SetWindowTitle IGNORE_THIS_VERSION_OF_SDL_SetWindowTitle +#define SDL_GetWindowTitle IGNORE_THIS_VERSION_OF_SDL_GetWindowTitle +#define SDL_SetWindowIcon IGNORE_THIS_VERSION_OF_SDL_SetWindowIcon +#define SDL_SetWindowData IGNORE_THIS_VERSION_OF_SDL_SetWindowData +#define SDL_GetWindowData IGNORE_THIS_VERSION_OF_SDL_GetWindowData +#define SDL_SetWindowPosition IGNORE_THIS_VERSION_OF_SDL_SetWindowPosition +#define SDL_GetWindowPosition IGNORE_THIS_VERSION_OF_SDL_GetWindowPosition +#define SDL_SetWindowSize IGNORE_THIS_VERSION_OF_SDL_SetWindowSize +#define SDL_GetWindowSize IGNORE_THIS_VERSION_OF_SDL_GetWindowSize +#define SDL_SetWindowMinimumSize IGNORE_THIS_VERSION_OF_SDL_SetWindowMinimumSize +#define SDL_GetWindowMinimumSize IGNORE_THIS_VERSION_OF_SDL_GetWindowMinimumSize +#define SDL_SetWindowMaximumSize IGNORE_THIS_VERSION_OF_SDL_SetWindowMaximumSize +#define SDL_GetWindowMaximumSize IGNORE_THIS_VERSION_OF_SDL_GetWindowMaximumSize +#define SDL_SetWindowBordered IGNORE_THIS_VERSION_OF_SDL_SetWindowBordered +#define SDL_ShowWindow IGNORE_THIS_VERSION_OF_SDL_ShowWindow +#define SDL_HideWindow IGNORE_THIS_VERSION_OF_SDL_HideWindow +#define SDL_RaiseWindow IGNORE_THIS_VERSION_OF_SDL_RaiseWindow +#define SDL_MaximizeWindow IGNORE_THIS_VERSION_OF_SDL_MaximizeWindow +#define SDL_MinimizeWindow IGNORE_THIS_VERSION_OF_SDL_MinimizeWindow +#define SDL_RestoreWindow IGNORE_THIS_VERSION_OF_SDL_RestoreWindow +#define SDL_SetWindowFullscreen IGNORE_THIS_VERSION_OF_SDL_SetWindowFullscreen +#define SDL_GetWindowSurface IGNORE_THIS_VERSION_OF_SDL_GetWindowSurface +#define SDL_UpdateWindowSurface IGNORE_THIS_VERSION_OF_SDL_UpdateWindowSurface +#define SDL_UpdateWindowSurfaceRects IGNORE_THIS_VERSION_OF_SDL_UpdateWindowSurfaceRects +#define SDL_SetWindowGrab IGNORE_THIS_VERSION_OF_SDL_SetWindowGrab +#define SDL_GetWindowGrab IGNORE_THIS_VERSION_OF_SDL_GetWindowGrab +#define SDL_SetWindowBrightness IGNORE_THIS_VERSION_OF_SDL_SetWindowBrightness +#define SDL_GetWindowBrightness IGNORE_THIS_VERSION_OF_SDL_GetWindowBrightness +#define SDL_SetWindowGammaRamp IGNORE_THIS_VERSION_OF_SDL_SetWindowGammaRamp +#define SDL_GetWindowGammaRamp IGNORE_THIS_VERSION_OF_SDL_GetWindowGammaRamp +#define SDL_DestroyWindow IGNORE_THIS_VERSION_OF_SDL_DestroyWindow +#define SDL_IsScreenSaverEnabled IGNORE_THIS_VERSION_OF_SDL_IsScreenSaverEnabled +#define SDL_EnableScreenSaver IGNORE_THIS_VERSION_OF_SDL_EnableScreenSaver +#define SDL_DisableScreenSaver IGNORE_THIS_VERSION_OF_SDL_DisableScreenSaver +#define SDL_GL_LoadLibrary IGNORE_THIS_VERSION_OF_SDL_GL_LoadLibrary +#define SDL_GL_GetProcAddress IGNORE_THIS_VERSION_OF_SDL_GL_GetProcAddress +#define SDL_GL_UnloadLibrary IGNORE_THIS_VERSION_OF_SDL_GL_UnloadLibrary +#define SDL_GL_ExtensionSupported IGNORE_THIS_VERSION_OF_SDL_GL_ExtensionSupported +#define SDL_GL_SetAttribute IGNORE_THIS_VERSION_OF_SDL_GL_SetAttribute +#define SDL_GL_GetAttribute IGNORE_THIS_VERSION_OF_SDL_GL_GetAttribute +#define SDL_GL_CreateContext IGNORE_THIS_VERSION_OF_SDL_GL_CreateContext +#define SDL_GL_MakeCurrent IGNORE_THIS_VERSION_OF_SDL_GL_MakeCurrent +#define SDL_GL_GetCurrentWindow IGNORE_THIS_VERSION_OF_SDL_GL_GetCurrentWindow +#define SDL_GL_GetCurrentContext IGNORE_THIS_VERSION_OF_SDL_GL_GetCurrentContext +#define SDL_GL_GetDrawableSize IGNORE_THIS_VERSION_OF_SDL_GL_GetDrawableSize +#define SDL_GL_SetSwapInterval IGNORE_THIS_VERSION_OF_SDL_GL_SetSwapInterval +#define SDL_GL_GetSwapInterval IGNORE_THIS_VERSION_OF_SDL_GL_GetSwapInterval +#define SDL_GL_SwapWindow IGNORE_THIS_VERSION_OF_SDL_GL_SwapWindow +#define SDL_GL_DeleteContext IGNORE_THIS_VERSION_OF_SDL_GL_DeleteContext +#define SDL_vsscanf IGNORE_THIS_VERSION_OF_SDL_vsscanf +#define SDL_GameControllerAddMappingsFromRW IGNORE_THIS_VERSION_OF_SDL_GameControllerAddMappingsFromRW +#define SDL_GL_ResetAttributes IGNORE_THIS_VERSION_OF_SDL_GL_ResetAttributes +#define SDL_HasAVX IGNORE_THIS_VERSION_OF_SDL_HasAVX +#define SDL_GetDefaultAssertionHandler IGNORE_THIS_VERSION_OF_SDL_GetDefaultAssertionHandler +#define SDL_GetAssertionHandler IGNORE_THIS_VERSION_OF_SDL_GetAssertionHandler +#define SDL_DXGIGetOutputInfo IGNORE_THIS_VERSION_OF_SDL_DXGIGetOutputInfo +#define SDL_RenderIsClipEnabled IGNORE_THIS_VERSION_OF_SDL_RenderIsClipEnabled +#define SDL_WinRTRunApp IGNORE_THIS_VERSION_OF_SDL_WinRTRunApp +#define SDL_WarpMouseGlobal IGNORE_THIS_VERSION_OF_SDL_WarpMouseGlobal +#define SDL_WinRTGetFSPathUNICODE IGNORE_THIS_VERSION_OF_SDL_WinRTGetFSPathUNICODE +#define SDL_WinRTGetFSPathUTF8 IGNORE_THIS_VERSION_OF_SDL_WinRTGetFSPathUTF8 +#define SDL_sqrtf IGNORE_THIS_VERSION_OF_SDL_sqrtf +#define SDL_tan IGNORE_THIS_VERSION_OF_SDL_tan +#define SDL_tanf IGNORE_THIS_VERSION_OF_SDL_tanf +#define SDL_CaptureMouse IGNORE_THIS_VERSION_OF_SDL_CaptureMouse +#define SDL_SetWindowHitTest IGNORE_THIS_VERSION_OF_SDL_SetWindowHitTest +#define SDL_GetGlobalMouseState IGNORE_THIS_VERSION_OF_SDL_GetGlobalMouseState +#define SDL_HasAVX2 IGNORE_THIS_VERSION_OF_SDL_HasAVX2 +#define SDL_QueueAudio IGNORE_THIS_VERSION_OF_SDL_QueueAudio +#define SDL_GetQueuedAudioSize IGNORE_THIS_VERSION_OF_SDL_GetQueuedAudioSize +#define SDL_ClearQueuedAudio IGNORE_THIS_VERSION_OF_SDL_ClearQueuedAudio +#define SDL_GetGrabbedWindow IGNORE_THIS_VERSION_OF_SDL_GetGrabbedWindow +#define SDL_SetWindowsMessageHook IGNORE_THIS_VERSION_OF_SDL_SetWindowsMessageHook +#define SDL_JoystickCurrentPowerLevel IGNORE_THIS_VERSION_OF_SDL_JoystickCurrentPowerLevel +#define SDL_GameControllerFromInstanceID IGNORE_THIS_VERSION_OF_SDL_GameControllerFromInstanceID +#define SDL_JoystickFromInstanceID IGNORE_THIS_VERSION_OF_SDL_JoystickFromInstanceID +#define SDL_GetDisplayUsableBounds IGNORE_THIS_VERSION_OF_SDL_GetDisplayUsableBounds +#define SDL_GetWindowBordersSize IGNORE_THIS_VERSION_OF_SDL_GetWindowBordersSize +#define SDL_SetWindowOpacity IGNORE_THIS_VERSION_OF_SDL_SetWindowOpacity +#define SDL_GetWindowOpacity IGNORE_THIS_VERSION_OF_SDL_GetWindowOpacity +#define SDL_SetWindowInputFocus IGNORE_THIS_VERSION_OF_SDL_SetWindowInputFocus +#define SDL_SetWindowModalFor IGNORE_THIS_VERSION_OF_SDL_SetWindowModalFor +#define SDL_RenderSetIntegerScale IGNORE_THIS_VERSION_OF_SDL_RenderSetIntegerScale +#define SDL_RenderGetIntegerScale IGNORE_THIS_VERSION_OF_SDL_RenderGetIntegerScale +#define SDL_DequeueAudio IGNORE_THIS_VERSION_OF_SDL_DequeueAudio +#define SDL_SetWindowResizable IGNORE_THIS_VERSION_OF_SDL_SetWindowResizable +#define SDL_CreateRGBSurfaceWithFormat IGNORE_THIS_VERSION_OF_SDL_CreateRGBSurfaceWithFormat +#define SDL_CreateRGBSurfaceWithFormatFrom IGNORE_THIS_VERSION_OF_SDL_CreateRGBSurfaceWithFormatFrom +#define SDL_GetHintBoolean IGNORE_THIS_VERSION_OF_SDL_GetHintBoolean +#define SDL_JoystickGetDeviceVendor IGNORE_THIS_VERSION_OF_SDL_JoystickGetDeviceVendor +#define SDL_JoystickGetDeviceProduct IGNORE_THIS_VERSION_OF_SDL_JoystickGetDeviceProduct +#define SDL_JoystickGetDeviceProductVersion IGNORE_THIS_VERSION_OF_SDL_JoystickGetDeviceProductVersion +#define SDL_JoystickGetVendor IGNORE_THIS_VERSION_OF_SDL_JoystickGetVendor +#define SDL_JoystickGetProduct IGNORE_THIS_VERSION_OF_SDL_JoystickGetProduct +#define SDL_JoystickGetProductVersion IGNORE_THIS_VERSION_OF_SDL_JoystickGetProductVersion +#define SDL_GameControllerGetVendor IGNORE_THIS_VERSION_OF_SDL_GameControllerGetVendor +#define SDL_GameControllerGetProduct IGNORE_THIS_VERSION_OF_SDL_GameControllerGetProduct +#define SDL_GameControllerGetProductVersion IGNORE_THIS_VERSION_OF_SDL_GameControllerGetProductVersion +#define SDL_HasNEON IGNORE_THIS_VERSION_OF_SDL_HasNEON +#define SDL_GameControllerNumMappings IGNORE_THIS_VERSION_OF_SDL_GameControllerNumMappings +#define SDL_GameControllerMappingForIndex IGNORE_THIS_VERSION_OF_SDL_GameControllerMappingForIndex +#define SDL_JoystickGetAxisInitialState IGNORE_THIS_VERSION_OF_SDL_JoystickGetAxisInitialState +#define SDL_JoystickGetDeviceType IGNORE_THIS_VERSION_OF_SDL_JoystickGetDeviceType +#define SDL_JoystickGetType IGNORE_THIS_VERSION_OF_SDL_JoystickGetType +#define SDL_MemoryBarrierReleaseFunction IGNORE_THIS_VERSION_OF_SDL_MemoryBarrierReleaseFunction +#define SDL_MemoryBarrierAcquireFunction IGNORE_THIS_VERSION_OF_SDL_MemoryBarrierAcquireFunction +#define SDL_JoystickGetDeviceInstanceID IGNORE_THIS_VERSION_OF_SDL_JoystickGetDeviceInstanceID +#define SDL_utf8strlen IGNORE_THIS_VERSION_OF_SDL_utf8strlen +#define SDL_LoadFile_RW IGNORE_THIS_VERSION_OF_SDL_LoadFile_RW +#define SDL_wcscmp IGNORE_THIS_VERSION_OF_SDL_wcscmp +#define SDL_ComposeCustomBlendMode IGNORE_THIS_VERSION_OF_SDL_ComposeCustomBlendMode +#define SDL_DuplicateSurface IGNORE_THIS_VERSION_OF_SDL_DuplicateSurface +#define SDL_Vulkan_LoadLibrary IGNORE_THIS_VERSION_OF_SDL_Vulkan_LoadLibrary +#define SDL_Vulkan_GetVkGetInstanceProcAddr IGNORE_THIS_VERSION_OF_SDL_Vulkan_GetVkGetInstanceProcAddr +#define SDL_Vulkan_UnloadLibrary IGNORE_THIS_VERSION_OF_SDL_Vulkan_UnloadLibrary +#define SDL_Vulkan_GetInstanceExtensions IGNORE_THIS_VERSION_OF_SDL_Vulkan_GetInstanceExtensions +#define SDL_Vulkan_CreateSurface IGNORE_THIS_VERSION_OF_SDL_Vulkan_CreateSurface +#define SDL_Vulkan_GetDrawableSize IGNORE_THIS_VERSION_OF_SDL_Vulkan_GetDrawableSize +#define SDL_LockJoysticks IGNORE_THIS_VERSION_OF_SDL_LockJoysticks +#define SDL_UnlockJoysticks IGNORE_THIS_VERSION_OF_SDL_UnlockJoysticks +#define SDL_GetMemoryFunctions IGNORE_THIS_VERSION_OF_SDL_GetMemoryFunctions +#define SDL_SetMemoryFunctions IGNORE_THIS_VERSION_OF_SDL_SetMemoryFunctions +#define SDL_GetNumAllocations IGNORE_THIS_VERSION_OF_SDL_GetNumAllocations +#define SDL_NewAudioStream IGNORE_THIS_VERSION_OF_SDL_NewAudioStream +#define SDL_AudioStreamPut IGNORE_THIS_VERSION_OF_SDL_AudioStreamPut +#define SDL_AudioStreamGet IGNORE_THIS_VERSION_OF_SDL_AudioStreamGet +#define SDL_AudioStreamClear IGNORE_THIS_VERSION_OF_SDL_AudioStreamClear +#define SDL_AudioStreamAvailable IGNORE_THIS_VERSION_OF_SDL_AudioStreamAvailable +#define SDL_FreeAudioStream IGNORE_THIS_VERSION_OF_SDL_FreeAudioStream +#define SDL_AudioStreamFlush IGNORE_THIS_VERSION_OF_SDL_AudioStreamFlush +#define SDL_acosf IGNORE_THIS_VERSION_OF_SDL_acosf +#define SDL_asinf IGNORE_THIS_VERSION_OF_SDL_asinf +#define SDL_atanf IGNORE_THIS_VERSION_OF_SDL_atanf +#define SDL_atan2f IGNORE_THIS_VERSION_OF_SDL_atan2f +#define SDL_ceilf IGNORE_THIS_VERSION_OF_SDL_ceilf +#define SDL_copysignf IGNORE_THIS_VERSION_OF_SDL_copysignf +#define SDL_fabsf IGNORE_THIS_VERSION_OF_SDL_fabsf +#define SDL_floorf IGNORE_THIS_VERSION_OF_SDL_floorf +#define SDL_logf IGNORE_THIS_VERSION_OF_SDL_logf +#define SDL_powf IGNORE_THIS_VERSION_OF_SDL_powf +#define SDL_scalbnf IGNORE_THIS_VERSION_OF_SDL_scalbnf +#define SDL_fmod IGNORE_THIS_VERSION_OF_SDL_fmod +#define SDL_fmodf IGNORE_THIS_VERSION_OF_SDL_fmodf +#define SDL_SetYUVConversionMode IGNORE_THIS_VERSION_OF_SDL_SetYUVConversionMode +#define SDL_GetYUVConversionMode IGNORE_THIS_VERSION_OF_SDL_GetYUVConversionMode +#define SDL_GetYUVConversionModeForResolution IGNORE_THIS_VERSION_OF_SDL_GetYUVConversionModeForResolution +#define SDL_RenderGetMetalLayer IGNORE_THIS_VERSION_OF_SDL_RenderGetMetalLayer +#define SDL_RenderGetMetalCommandEncoder IGNORE_THIS_VERSION_OF_SDL_RenderGetMetalCommandEncoder +#define SDL_IsAndroidTV IGNORE_THIS_VERSION_OF_SDL_IsAndroidTV +#define SDL_WinRTGetDeviceFamily IGNORE_THIS_VERSION_OF_SDL_WinRTGetDeviceFamily +#define SDL_log10 IGNORE_THIS_VERSION_OF_SDL_log10 +#define SDL_log10f IGNORE_THIS_VERSION_OF_SDL_log10f +#define SDL_GameControllerMappingForDeviceIndex IGNORE_THIS_VERSION_OF_SDL_GameControllerMappingForDeviceIndex +#define SDL_LinuxSetThreadPriority IGNORE_THIS_VERSION_OF_SDL_LinuxSetThreadPriority +#define SDL_HasAVX512F IGNORE_THIS_VERSION_OF_SDL_HasAVX512F +#define SDL_IsChromebook IGNORE_THIS_VERSION_OF_SDL_IsChromebook +#define SDL_IsDeXMode IGNORE_THIS_VERSION_OF_SDL_IsDeXMode +#define SDL_AndroidBackButton IGNORE_THIS_VERSION_OF_SDL_AndroidBackButton +#define SDL_exp IGNORE_THIS_VERSION_OF_SDL_exp +#define SDL_expf IGNORE_THIS_VERSION_OF_SDL_expf +#define SDL_wcsdup IGNORE_THIS_VERSION_OF_SDL_wcsdup +#define SDL_GameControllerRumble IGNORE_THIS_VERSION_OF_SDL_GameControllerRumble +#define SDL_JoystickRumble IGNORE_THIS_VERSION_OF_SDL_JoystickRumble +#define SDL_NumSensors IGNORE_THIS_VERSION_OF_SDL_NumSensors +#define SDL_SensorGetDeviceName IGNORE_THIS_VERSION_OF_SDL_SensorGetDeviceName +#define SDL_SensorGetDeviceType IGNORE_THIS_VERSION_OF_SDL_SensorGetDeviceType +#define SDL_SensorGetDeviceNonPortableType IGNORE_THIS_VERSION_OF_SDL_SensorGetDeviceNonPortableType +#define SDL_SensorGetDeviceInstanceID IGNORE_THIS_VERSION_OF_SDL_SensorGetDeviceInstanceID +#define SDL_SensorOpen IGNORE_THIS_VERSION_OF_SDL_SensorOpen +#define SDL_SensorFromInstanceID IGNORE_THIS_VERSION_OF_SDL_SensorFromInstanceID +#define SDL_SensorGetName IGNORE_THIS_VERSION_OF_SDL_SensorGetName +#define SDL_SensorGetType IGNORE_THIS_VERSION_OF_SDL_SensorGetType +#define SDL_SensorGetNonPortableType IGNORE_THIS_VERSION_OF_SDL_SensorGetNonPortableType +#define SDL_SensorGetInstanceID IGNORE_THIS_VERSION_OF_SDL_SensorGetInstanceID +#define SDL_SensorGetData IGNORE_THIS_VERSION_OF_SDL_SensorGetData +#define SDL_SensorClose IGNORE_THIS_VERSION_OF_SDL_SensorClose +#define SDL_SensorUpdate IGNORE_THIS_VERSION_OF_SDL_SensorUpdate +#define SDL_IsTablet IGNORE_THIS_VERSION_OF_SDL_IsTablet +#define SDL_GetDisplayOrientation IGNORE_THIS_VERSION_OF_SDL_GetDisplayOrientation +#define SDL_HasColorKey IGNORE_THIS_VERSION_OF_SDL_HasColorKey +#define SDL_CreateThreadWithStackSize IGNORE_THIS_VERSION_OF_SDL_CreateThreadWithStackSize +#define SDL_JoystickGetDevicePlayerIndex IGNORE_THIS_VERSION_OF_SDL_JoystickGetDevicePlayerIndex +#define SDL_JoystickGetPlayerIndex IGNORE_THIS_VERSION_OF_SDL_JoystickGetPlayerIndex +#define SDL_GameControllerGetPlayerIndex IGNORE_THIS_VERSION_OF_SDL_GameControllerGetPlayerIndex +#define SDL_RenderFlush IGNORE_THIS_VERSION_OF_SDL_RenderFlush +#define SDL_RenderDrawPointF IGNORE_THIS_VERSION_OF_SDL_RenderDrawPointF +#define SDL_RenderDrawPointsF IGNORE_THIS_VERSION_OF_SDL_RenderDrawPointsF +#define SDL_RenderDrawLineF IGNORE_THIS_VERSION_OF_SDL_RenderDrawLineF +#define SDL_RenderDrawLinesF IGNORE_THIS_VERSION_OF_SDL_RenderDrawLinesF +#define SDL_RenderDrawRectF IGNORE_THIS_VERSION_OF_SDL_RenderDrawRectF +#define SDL_RenderDrawRectsF IGNORE_THIS_VERSION_OF_SDL_RenderDrawRectsF +#define SDL_RenderFillRectF IGNORE_THIS_VERSION_OF_SDL_RenderFillRectF +#define SDL_RenderFillRectsF IGNORE_THIS_VERSION_OF_SDL_RenderFillRectsF +#define SDL_RenderCopyF IGNORE_THIS_VERSION_OF_SDL_RenderCopyF +#define SDL_RenderCopyExF IGNORE_THIS_VERSION_OF_SDL_RenderCopyExF +#define SDL_GetTouchDeviceType IGNORE_THIS_VERSION_OF_SDL_GetTouchDeviceType +#define SDL_UIKitRunApp IGNORE_THIS_VERSION_OF_SDL_UIKitRunApp +#define SDL_SIMDGetAlignment IGNORE_THIS_VERSION_OF_SDL_SIMDGetAlignment +#define SDL_SIMDAlloc IGNORE_THIS_VERSION_OF_SDL_SIMDAlloc +#define SDL_SIMDFree IGNORE_THIS_VERSION_OF_SDL_SIMDFree +#define SDL_RWsize IGNORE_THIS_VERSION_OF_SDL_RWsize +#define SDL_RWseek IGNORE_THIS_VERSION_OF_SDL_RWseek +#define SDL_RWtell IGNORE_THIS_VERSION_OF_SDL_RWtell +#define SDL_RWread IGNORE_THIS_VERSION_OF_SDL_RWread +#define SDL_RWwrite IGNORE_THIS_VERSION_OF_SDL_RWwrite +#define SDL_RWclose IGNORE_THIS_VERSION_OF_SDL_RWclose +#define SDL_LoadFile IGNORE_THIS_VERSION_OF_SDL_LoadFile +#define SDL_Metal_CreateView IGNORE_THIS_VERSION_OF_SDL_Metal_CreateView +#define SDL_Metal_DestroyView IGNORE_THIS_VERSION_OF_SDL_Metal_DestroyView +#define SDL_LockTextureToSurface IGNORE_THIS_VERSION_OF_SDL_LockTextureToSurface +#define SDL_HasARMSIMD IGNORE_THIS_VERSION_OF_SDL_HasARMSIMD +#define SDL_strtokr IGNORE_THIS_VERSION_OF_SDL_strtokr +#define SDL_wcsstr IGNORE_THIS_VERSION_OF_SDL_wcsstr +#define SDL_wcsncmp IGNORE_THIS_VERSION_OF_SDL_wcsncmp +#define SDL_GameControllerTypeForIndex IGNORE_THIS_VERSION_OF_SDL_GameControllerTypeForIndex +#define SDL_GameControllerGetType IGNORE_THIS_VERSION_OF_SDL_GameControllerGetType +#define SDL_GameControllerFromPlayerIndex IGNORE_THIS_VERSION_OF_SDL_GameControllerFromPlayerIndex +#define SDL_GameControllerSetPlayerIndex IGNORE_THIS_VERSION_OF_SDL_GameControllerSetPlayerIndex +#define SDL_JoystickFromPlayerIndex IGNORE_THIS_VERSION_OF_SDL_JoystickFromPlayerIndex +#define SDL_JoystickSetPlayerIndex IGNORE_THIS_VERSION_OF_SDL_JoystickSetPlayerIndex +#define SDL_SetTextureScaleMode IGNORE_THIS_VERSION_OF_SDL_SetTextureScaleMode +#define SDL_GetTextureScaleMode IGNORE_THIS_VERSION_OF_SDL_GetTextureScaleMode +#define SDL_OnApplicationWillTerminate IGNORE_THIS_VERSION_OF_SDL_OnApplicationWillTerminate +#define SDL_OnApplicationDidReceiveMemoryWarning IGNORE_THIS_VERSION_OF_SDL_OnApplicationDidReceiveMemoryWarning +#define SDL_OnApplicationWillResignActive IGNORE_THIS_VERSION_OF_SDL_OnApplicationWillResignActive +#define SDL_OnApplicationDidEnterBackground IGNORE_THIS_VERSION_OF_SDL_OnApplicationDidEnterBackground +#define SDL_OnApplicationWillEnterForeground IGNORE_THIS_VERSION_OF_SDL_OnApplicationWillEnterForeground +#define SDL_OnApplicationDidBecomeActive IGNORE_THIS_VERSION_OF_SDL_OnApplicationDidBecomeActive +#define SDL_OnApplicationDidChangeStatusBarOrientation IGNORE_THIS_VERSION_OF_SDL_OnApplicationDidChangeStatusBarOrientation +#define SDL_GetAndroidSDKVersion IGNORE_THIS_VERSION_OF_SDL_GetAndroidSDKVersion +#define SDL_isupper IGNORE_THIS_VERSION_OF_SDL_isupper +#define SDL_islower IGNORE_THIS_VERSION_OF_SDL_islower +#define SDL_JoystickAttachVirtual IGNORE_THIS_VERSION_OF_SDL_JoystickAttachVirtual +#define SDL_JoystickDetachVirtual IGNORE_THIS_VERSION_OF_SDL_JoystickDetachVirtual +#define SDL_JoystickIsVirtual IGNORE_THIS_VERSION_OF_SDL_JoystickIsVirtual +#define SDL_JoystickSetVirtualAxis IGNORE_THIS_VERSION_OF_SDL_JoystickSetVirtualAxis +#define SDL_JoystickSetVirtualButton IGNORE_THIS_VERSION_OF_SDL_JoystickSetVirtualButton +#define SDL_JoystickSetVirtualHat IGNORE_THIS_VERSION_OF_SDL_JoystickSetVirtualHat +#define SDL_GetErrorMsg IGNORE_THIS_VERSION_OF_SDL_GetErrorMsg +#define SDL_LockSensors IGNORE_THIS_VERSION_OF_SDL_LockSensors +#define SDL_UnlockSensors IGNORE_THIS_VERSION_OF_SDL_UnlockSensors +#define SDL_Metal_GetLayer IGNORE_THIS_VERSION_OF_SDL_Metal_GetLayer +#define SDL_Metal_GetDrawableSize IGNORE_THIS_VERSION_OF_SDL_Metal_GetDrawableSize +#define SDL_trunc IGNORE_THIS_VERSION_OF_SDL_trunc +#define SDL_truncf IGNORE_THIS_VERSION_OF_SDL_truncf +#define SDL_GetPreferredLocales IGNORE_THIS_VERSION_OF_SDL_GetPreferredLocales +#define SDL_SIMDRealloc IGNORE_THIS_VERSION_OF_SDL_SIMDRealloc +#define SDL_AndroidRequestPermission IGNORE_THIS_VERSION_OF_SDL_AndroidRequestPermission +#define SDL_OpenURL IGNORE_THIS_VERSION_OF_SDL_OpenURL +#define SDL_HasSurfaceRLE IGNORE_THIS_VERSION_OF_SDL_HasSurfaceRLE +#define SDL_GameControllerHasLED IGNORE_THIS_VERSION_OF_SDL_GameControllerHasLED +#define SDL_GameControllerSetLED IGNORE_THIS_VERSION_OF_SDL_GameControllerSetLED +#define SDL_JoystickHasLED IGNORE_THIS_VERSION_OF_SDL_JoystickHasLED +#define SDL_JoystickSetLED IGNORE_THIS_VERSION_OF_SDL_JoystickSetLED +#define SDL_GameControllerRumbleTriggers IGNORE_THIS_VERSION_OF_SDL_GameControllerRumbleTriggers +#define SDL_JoystickRumbleTriggers IGNORE_THIS_VERSION_OF_SDL_JoystickRumbleTriggers +#define SDL_GameControllerHasAxis IGNORE_THIS_VERSION_OF_SDL_GameControllerHasAxis +#define SDL_GameControllerHasButton IGNORE_THIS_VERSION_OF_SDL_GameControllerHasButton +#define SDL_GameControllerGetNumTouchpads IGNORE_THIS_VERSION_OF_SDL_GameControllerGetNumTouchpads +#define SDL_GameControllerGetNumTouchpadFingers IGNORE_THIS_VERSION_OF_SDL_GameControllerGetNumTouchpadFingers +#define SDL_GameControllerGetTouchpadFinger IGNORE_THIS_VERSION_OF_SDL_GameControllerGetTouchpadFinger +#define SDL_crc32 IGNORE_THIS_VERSION_OF_SDL_crc32 +#define SDL_GameControllerGetSerial IGNORE_THIS_VERSION_OF_SDL_GameControllerGetSerial +#define SDL_JoystickGetSerial IGNORE_THIS_VERSION_OF_SDL_JoystickGetSerial +#define SDL_GameControllerHasSensor IGNORE_THIS_VERSION_OF_SDL_GameControllerHasSensor +#define SDL_GameControllerSetSensorEnabled IGNORE_THIS_VERSION_OF_SDL_GameControllerSetSensorEnabled +#define SDL_GameControllerIsSensorEnabled IGNORE_THIS_VERSION_OF_SDL_GameControllerIsSensorEnabled +#define SDL_GameControllerGetSensorData IGNORE_THIS_VERSION_OF_SDL_GameControllerGetSensorData +#define SDL_wcscasecmp IGNORE_THIS_VERSION_OF_SDL_wcscasecmp +#define SDL_wcsncasecmp IGNORE_THIS_VERSION_OF_SDL_wcsncasecmp +#define SDL_round IGNORE_THIS_VERSION_OF_SDL_round +#define SDL_roundf IGNORE_THIS_VERSION_OF_SDL_roundf +#define SDL_lround IGNORE_THIS_VERSION_OF_SDL_lround +#define SDL_lroundf IGNORE_THIS_VERSION_OF_SDL_lroundf +#define SDL_SoftStretchLinear IGNORE_THIS_VERSION_OF_SDL_SoftStretchLinear +#define SDL_RenderGetD3D11Device IGNORE_THIS_VERSION_OF_SDL_RenderGetD3D11Device +#define SDL_UpdateNVTexture IGNORE_THIS_VERSION_OF_SDL_UpdateNVTexture +#define SDL_SetWindowKeyboardGrab IGNORE_THIS_VERSION_OF_SDL_SetWindowKeyboardGrab +#define SDL_SetWindowMouseGrab IGNORE_THIS_VERSION_OF_SDL_SetWindowMouseGrab +#define SDL_GetWindowKeyboardGrab IGNORE_THIS_VERSION_OF_SDL_GetWindowKeyboardGrab +#define SDL_GetWindowMouseGrab IGNORE_THIS_VERSION_OF_SDL_GetWindowMouseGrab +#define SDL_isalpha IGNORE_THIS_VERSION_OF_SDL_isalpha +#define SDL_isalnum IGNORE_THIS_VERSION_OF_SDL_isalnum +#define SDL_isblank IGNORE_THIS_VERSION_OF_SDL_isblank +#define SDL_iscntrl IGNORE_THIS_VERSION_OF_SDL_iscntrl +#define SDL_isxdigit IGNORE_THIS_VERSION_OF_SDL_isxdigit +#define SDL_ispunct IGNORE_THIS_VERSION_OF_SDL_ispunct +#define SDL_isprint IGNORE_THIS_VERSION_OF_SDL_isprint +#define SDL_isgraph IGNORE_THIS_VERSION_OF_SDL_isgraph +#define SDL_AndroidShowToast IGNORE_THIS_VERSION_OF_SDL_AndroidShowToast +#define SDL_GetAudioDeviceSpec IGNORE_THIS_VERSION_OF_SDL_GetAudioDeviceSpec +#define SDL_TLSCleanup IGNORE_THIS_VERSION_OF_SDL_TLSCleanup +#define SDL_SetWindowAlwaysOnTop IGNORE_THIS_VERSION_OF_SDL_SetWindowAlwaysOnTop +#define SDL_FlashWindow IGNORE_THIS_VERSION_OF_SDL_FlashWindow +#define SDL_GameControllerSendEffect IGNORE_THIS_VERSION_OF_SDL_GameControllerSendEffect +#define SDL_JoystickSendEffect IGNORE_THIS_VERSION_OF_SDL_JoystickSendEffect +#define SDL_GameControllerGetSensorDataRate IGNORE_THIS_VERSION_OF_SDL_GameControllerGetSensorDataRate +#define SDL_SetTextureUserData IGNORE_THIS_VERSION_OF_SDL_SetTextureUserData +#define SDL_GetTextureUserData IGNORE_THIS_VERSION_OF_SDL_GetTextureUserData +#define SDL_RenderGeometry IGNORE_THIS_VERSION_OF_SDL_RenderGeometry +#define SDL_RenderGeometryRaw IGNORE_THIS_VERSION_OF_SDL_RenderGeometryRaw +#define SDL_RenderSetVSync IGNORE_THIS_VERSION_OF_SDL_RenderSetVSync +#define SDL_asprintf IGNORE_THIS_VERSION_OF_SDL_asprintf +#define SDL_vasprintf IGNORE_THIS_VERSION_OF_SDL_vasprintf +#define SDL_GetWindowICCProfile IGNORE_THIS_VERSION_OF_SDL_GetWindowICCProfile +#define SDL_GetTicks64 IGNORE_THIS_VERSION_OF_SDL_GetTicks64 +#define SDL_LinuxSetThreadPriorityAndPolicy IGNORE_THIS_VERSION_OF_SDL_LinuxSetThreadPriorityAndPolicy +#define SDL_GameControllerGetAppleSFSymbolsNameForButton IGNORE_THIS_VERSION_OF_SDL_GameControllerGetAppleSFSymbolsNameForButton +#define SDL_GameControllerGetAppleSFSymbolsNameForAxis IGNORE_THIS_VERSION_OF_SDL_GameControllerGetAppleSFSymbolsNameForAxis +#define SDL_hid_init IGNORE_THIS_VERSION_OF_SDL_hid_init +#define SDL_hid_exit IGNORE_THIS_VERSION_OF_SDL_hid_exit +#define SDL_hid_device_change_count IGNORE_THIS_VERSION_OF_SDL_hid_device_change_count +#define SDL_hid_enumerate IGNORE_THIS_VERSION_OF_SDL_hid_enumerate +#define SDL_hid_free_enumeration IGNORE_THIS_VERSION_OF_SDL_hid_free_enumeration +#define SDL_hid_open IGNORE_THIS_VERSION_OF_SDL_hid_open +#define SDL_hid_open_path IGNORE_THIS_VERSION_OF_SDL_hid_open_path +#define SDL_hid_write IGNORE_THIS_VERSION_OF_SDL_hid_write +#define SDL_hid_read_timeout IGNORE_THIS_VERSION_OF_SDL_hid_read_timeout +#define SDL_hid_read IGNORE_THIS_VERSION_OF_SDL_hid_read +#define SDL_hid_set_nonblocking IGNORE_THIS_VERSION_OF_SDL_hid_set_nonblocking +#define SDL_hid_send_feature_report IGNORE_THIS_VERSION_OF_SDL_hid_send_feature_report +#define SDL_hid_get_feature_report IGNORE_THIS_VERSION_OF_SDL_hid_get_feature_report +#define SDL_hid_close IGNORE_THIS_VERSION_OF_SDL_hid_close +#define SDL_hid_get_manufacturer_string IGNORE_THIS_VERSION_OF_SDL_hid_get_manufacturer_string +#define SDL_hid_get_product_string IGNORE_THIS_VERSION_OF_SDL_hid_get_product_string +#define SDL_hid_get_serial_number_string IGNORE_THIS_VERSION_OF_SDL_hid_get_serial_number_string +#define SDL_hid_get_indexed_string IGNORE_THIS_VERSION_OF_SDL_hid_get_indexed_string +#define SDL_SetWindowMouseRect IGNORE_THIS_VERSION_OF_SDL_SetWindowMouseRect +#define SDL_GetWindowMouseRect IGNORE_THIS_VERSION_OF_SDL_GetWindowMouseRect +#define SDL_RenderWindowToLogical IGNORE_THIS_VERSION_OF_SDL_RenderWindowToLogical +#define SDL_RenderLogicalToWindow IGNORE_THIS_VERSION_OF_SDL_RenderLogicalToWindow +#define SDL_JoystickHasRumble IGNORE_THIS_VERSION_OF_SDL_JoystickHasRumble +#define SDL_JoystickHasRumbleTriggers IGNORE_THIS_VERSION_OF_SDL_JoystickHasRumbleTriggers +#define SDL_GameControllerHasRumble IGNORE_THIS_VERSION_OF_SDL_GameControllerHasRumble +#define SDL_GameControllerHasRumbleTriggers IGNORE_THIS_VERSION_OF_SDL_GameControllerHasRumbleTriggers +#define SDL_hid_ble_scan IGNORE_THIS_VERSION_OF_SDL_hid_ble_scan +#define SDL_PremultiplyAlpha IGNORE_THIS_VERSION_OF_SDL_PremultiplyAlpha +#define SDL_AndroidSendMessage IGNORE_THIS_VERSION_OF_SDL_AndroidSendMessage +#define SDL_GetTouchName IGNORE_THIS_VERSION_OF_SDL_GetTouchName +#define SDL_ClearComposition IGNORE_THIS_VERSION_OF_SDL_ClearComposition +#define SDL_IsTextInputShown IGNORE_THIS_VERSION_OF_SDL_IsTextInputShown +#define SDL_HasIntersectionF IGNORE_THIS_VERSION_OF_SDL_HasIntersectionF +#define SDL_IntersectFRect IGNORE_THIS_VERSION_OF_SDL_IntersectFRect +#define SDL_UnionFRect IGNORE_THIS_VERSION_OF_SDL_UnionFRect +#define SDL_EncloseFPoints IGNORE_THIS_VERSION_OF_SDL_EncloseFPoints +#define SDL_IntersectFRectAndLine IGNORE_THIS_VERSION_OF_SDL_IntersectFRectAndLine +#define SDL_RenderGetWindow IGNORE_THIS_VERSION_OF_SDL_RenderGetWindow +#define SDL_bsearch IGNORE_THIS_VERSION_OF_SDL_bsearch +#define SDL_GameControllerPathForIndex IGNORE_THIS_VERSION_OF_SDL_GameControllerPathForIndex +#define SDL_GameControllerPath IGNORE_THIS_VERSION_OF_SDL_GameControllerPath +#define SDL_JoystickPathForIndex IGNORE_THIS_VERSION_OF_SDL_JoystickPathForIndex +#define SDL_JoystickPath IGNORE_THIS_VERSION_OF_SDL_JoystickPath +#define SDL_JoystickAttachVirtualEx IGNORE_THIS_VERSION_OF_SDL_JoystickAttachVirtualEx +#define SDL_GameControllerGetFirmwareVersion IGNORE_THIS_VERSION_OF_SDL_GameControllerGetFirmwareVersion +#define SDL_JoystickGetFirmwareVersion IGNORE_THIS_VERSION_OF_SDL_JoystickGetFirmwareVersion +#define SDL_GUIDToString IGNORE_THIS_VERSION_OF_SDL_GUIDToString +#define SDL_GUIDFromString IGNORE_THIS_VERSION_OF_SDL_GUIDFromString +#define SDL_HasLSX IGNORE_THIS_VERSION_OF_SDL_HasLSX +#define SDL_HasLASX IGNORE_THIS_VERSION_OF_SDL_HasLASX +#define SDL_RenderGetD3D12Device IGNORE_THIS_VERSION_OF_SDL_RenderGetD3D12Device +#define SDL_utf8strnlen IGNORE_THIS_VERSION_OF_SDL_utf8strnlen +#define SDL_GDKGetTaskQueue IGNORE_THIS_VERSION_OF_SDL_GDKGetTaskQueue +#define SDL_GDKRunApp IGNORE_THIS_VERSION_OF_SDL_GDKRunApp +#define SDL_GetOriginalMemoryFunctions IGNORE_THIS_VERSION_OF_SDL_GetOriginalMemoryFunctions +#define SDL_ResetKeyboard IGNORE_THIS_VERSION_OF_SDL_ResetKeyboard +#define SDL_GetDefaultAudioInfo IGNORE_THIS_VERSION_OF_SDL_GetDefaultAudioInfo +#define SDL_GetPointDisplayIndex IGNORE_THIS_VERSION_OF_SDL_GetPointDisplayIndex +#define SDL_GetRectDisplayIndex IGNORE_THIS_VERSION_OF_SDL_GetRectDisplayIndex +#define SDL_ResetHint IGNORE_THIS_VERSION_OF_SDL_ResetHint +#define SDL_crc16 IGNORE_THIS_VERSION_OF_SDL_crc16 +#define SDL_GetWindowSizeInPixels IGNORE_THIS_VERSION_OF_SDL_GetWindowSizeInPixels +#define SDL_GetJoystickGUIDInfo IGNORE_THIS_VERSION_OF_SDL_GetJoystickGUIDInfo +#define SDL_SetPrimarySelectionText IGNORE_THIS_VERSION_OF_SDL_SetPrimarySelectionText +#define SDL_GetPrimarySelectionText IGNORE_THIS_VERSION_OF_SDL_GetPrimarySelectionText +#define SDL_HasPrimarySelectionText IGNORE_THIS_VERSION_OF_SDL_HasPrimarySelectionText +#define SDL_GameControllerGetSensorDataWithTimestamp IGNORE_THIS_VERSION_OF_SDL_GameControllerGetSensorDataWithTimestamp +#define SDL_SensorGetDataWithTimestamp IGNORE_THIS_VERSION_OF_SDL_SensorGetDataWithTimestamp +#define SDL_ResetHints IGNORE_THIS_VERSION_OF_SDL_ResetHints +#define SDL_strcasestr IGNORE_THIS_VERSION_OF_SDL_strcasestr +#define SDL_GDKSuspendComplete IGNORE_THIS_VERSION_OF_SDL_GDKSuspendComplete /* *** HACK HACK HACK: * *** Avoid including SDL_thread.h: it defines SDL_CreateThread() as a macro */ @@ -158,95 +937,9 @@ typedef void (__cdecl *pfnSDL_CurrentEndThread) (unsigned); #undef CreateMutex #endif /* _WIN32 */ -#undef SDL_Log -#undef SDL_GetVersion -#undef SDL_ReportAssertion -#undef SDL_Error -#undef SDL_SetError -#undef SDL_PollEvent -#undef SDL_PushEvent -#undef SDL_EventState -#undef SDL_PeepEvents -#undef SDL_WaitEvent -#undef SDL_SetEventFilter -#undef SDL_GetEventFilter -#undef SDL_CreateRGBSurface -#undef SDL_CreateRGBSurfaceFrom -#undef SDL_FreeSurface -#undef SDL_SetClipRect -#undef SDL_GetClipRect -#undef SDL_FillRect -#undef SDL_GetRGB -#undef SDL_GetRGBA -#undef SDL_MapRGB -#undef SDL_MapRGBA -#undef SDL_CreateCursor -#undef SDL_SetCursor -#undef SDL_GetCursor -#undef SDL_FreeCursor -#undef SDL_UpdateRect -#undef SDL_UpdateRects -#undef SDL_GetMouseState -#undef SDL_GetRelativeMouseState -#undef SDL_GL_SetAttribute -#undef SDL_GL_GetAttribute -#undef SDL_CreateThread -#undef SDL_AddTimer -#undef SDL_RemoveTimer -#undef SDL_AllocRW -#undef SDL_FreeRW -#undef SDL_RWFromFile -#undef SDL_RWFromFP -#undef SDL_RWFromMem -#undef SDL_RWFromConstMem -#undef SDL_ReadLE16 -#undef SDL_ReadBE16 -#undef SDL_ReadLE32 -#undef SDL_ReadBE32 -#undef SDL_ReadLE64 -#undef SDL_ReadBE64 -#undef SDL_WriteLE16 -#undef SDL_WriteBE16 -#undef SDL_WriteLE32 -#undef SDL_WriteBE32 -#undef SDL_WriteLE64 -#undef SDL_WriteBE64 -#undef SDL_GetThreadID -#undef SDL_ThreadID -#undef SDL_NumJoysticks -#undef SDL_JoystickNumAxes -#undef SDL_JoystickNumBalls -#undef SDL_JoystickNumHats -#undef SDL_JoystickNumButtons -#undef SDL_JoystickUpdate -#undef SDL_JoystickEventState -#undef SDL_JoystickGetAxis -#undef SDL_JoystickGetHat -#undef SDL_JoystickGetBall -#undef SDL_JoystickGetButton -#undef SDL_JoystickOpen -#undef SDL_JoystickClose -#undef SDL_JoystickName -#undef SDL_JoystickIndex -#undef SDL_JoystickOpened -#undef SDL_LoadBMP_RW -#undef SDL_SaveBMP_RW -#undef SDL_LoadWAV_RW -#undef SDL_UpperBlit -#undef SDL_LowerBlit -#undef SDL_SoftStretch -#undef SDL_ConvertSurface -#undef SDL_SetColorKey -#undef SDL_LockSurface -#undef SDL_UnlockSurface -#undef SDL_GetKeyName -#undef SDL_VideoInit -#undef SDL_BuildAudioCVT -#undef SDL_ConvertAudio -#undef SDL_MixAudio -#undef SDL_RegisterApp -#undef SDL_UnregisterApp - +#ifdef SDL_BlitSurface +#undef SDL_BlitSurface +#endif #ifdef SDL_mutexP #undef SDL_mutexP @@ -256,176 +949,3472 @@ typedef void (__cdecl *pfnSDL_CurrentEndThread) (unsigned); #undef SDL_mutexV #endif -#ifdef SDL_BlitSurface -#undef SDL_BlitSurface +#ifdef SDL_SetError +#undef SDL_SetError #endif -#ifdef SDL_malloc -#undef SDL_malloc +#ifdef SDL_Log +#undef SDL_Log #endif -#ifdef SDL_calloc -#undef SDL_calloc +#ifdef SDL_LogVerbose +#undef SDL_LogVerbose #endif -#ifdef SDL_realloc -#undef SDL_realloc +#ifdef SDL_LogDebug +#undef SDL_LogDebug #endif -#ifdef SDL_free -#undef SDL_free +#ifdef SDL_LogInfo +#undef SDL_LogInfo #endif -#ifdef SDL_getenv -#undef SDL_getenv +#ifdef SDL_LogWarn +#undef SDL_LogWarn #endif -#ifdef SDL_qsort -#undef SDL_qsort +#ifdef SDL_LogError +#undef SDL_LogError #endif -#ifdef SDL_memset -#undef SDL_memset +#ifdef SDL_LogCritical +#undef SDL_LogCritical #endif -#ifdef SDL_memcpy -#undef SDL_memcpy +#ifdef SDL_LogMessage +#undef SDL_LogMessage #endif -#ifdef SDL_revcpy -#undef SDL_revcpy +#ifdef SDL_sscanf +#undef SDL_sscanf #endif -#ifdef SDL_memcmp -#undef SDL_memcmp +#ifdef SDL_snprintf +#undef SDL_snprintf #endif -#ifdef SDL_strlen -#undef SDL_strlen +#ifdef SDL_CreateThread +#undef SDL_CreateThread #endif -#ifdef SDL_strlcpy -#undef SDL_strlcpy +#ifdef SDL_RWFromFP +#undef SDL_RWFromFP #endif -#ifdef SDL_strlcat -#undef SDL_strlcat +#ifdef SDL_RegisterApp +#undef SDL_RegisterApp #endif -#ifdef SDL_strdup -#undef SDL_strdup +#ifdef SDL_UnregisterApp +#undef SDL_UnregisterApp #endif -#ifdef SDL_strrev -#undef SDL_strrev +#ifdef SDL_Direct3D9GetAdapterIndex +#undef SDL_Direct3D9GetAdapterIndex #endif -#ifdef SDL_strupr -#undef SDL_strupr +#ifdef SDL_RenderGetD3D9Device +#undef SDL_RenderGetD3D9Device #endif -#ifdef SDL_strlwr -#undef SDL_strlwr +#ifdef SDL_iPhoneSetAnimationCallback +#undef SDL_iPhoneSetAnimationCallback #endif -#ifdef SDL_strchr -#undef SDL_strchr +#ifdef SDL_iPhoneSetEventPump +#undef SDL_iPhoneSetEventPump #endif -#ifdef SDL_strrchr -#undef SDL_strrchr +#ifdef SDL_AndroidGetJNIEnv +#undef SDL_AndroidGetJNIEnv #endif -#ifdef SDL_strstr -#undef SDL_strstr +#ifdef SDL_AndroidGetActivity +#undef SDL_AndroidGetActivity #endif -#ifdef SDL_ltoa -#undef SDL_ltoa +#ifdef SDL_AndroidGetInternalStoragePath +#undef SDL_AndroidGetInternalStoragePath #endif -#ifdef SDL_ultoa -#undef SDL_ultoa +#ifdef SDL_AndroidGetExternalStorageState +#undef SDL_AndroidGetExternalStorageState #endif -#ifdef SDL_strtol -#undef SDL_strtol +#ifdef SDL_AndroidGetExternalStoragePath +#undef SDL_AndroidGetExternalStoragePath #endif -#ifdef SDL_strtoul -#undef SDL_strtoul +#ifdef SDL_Init +#undef SDL_Init #endif -#ifdef SDL_lltoa -#undef SDL_lltoa +#ifdef SDL_InitSubSystem +#undef SDL_InitSubSystem #endif -#ifdef SDL_ulltoa -#undef SDL_ulltoa +#ifdef SDL_QuitSubSystem +#undef SDL_QuitSubSystem #endif -#ifdef SDL_strtoll -#undef SDL_strtoll +#ifdef SDL_WasInit +#undef SDL_WasInit +#endif + +#ifdef SDL_Quit +#undef SDL_Quit +#endif + +#ifdef SDL_ReportAssertion +#undef SDL_ReportAssertion +#endif + +#ifdef SDL_SetAssertionHandler +#undef SDL_SetAssertionHandler +#endif + +#ifdef SDL_GetAssertionReport +#undef SDL_GetAssertionReport +#endif + +#ifdef SDL_ResetAssertionReport +#undef SDL_ResetAssertionReport +#endif + +#ifdef SDL_AtomicTryLock +#undef SDL_AtomicTryLock +#endif + +#ifdef SDL_AtomicLock +#undef SDL_AtomicLock +#endif + +#ifdef SDL_AtomicUnlock +#undef SDL_AtomicUnlock +#endif + +#ifdef SDL_AtomicCAS +#undef SDL_AtomicCAS +#endif + +#ifdef SDL_AtomicSet +#undef SDL_AtomicSet +#endif + +#ifdef SDL_AtomicGet +#undef SDL_AtomicGet +#endif + +#ifdef SDL_AtomicAdd +#undef SDL_AtomicAdd +#endif + +#ifdef SDL_AtomicCASPtr +#undef SDL_AtomicCASPtr +#endif + +#ifdef SDL_AtomicSetPtr +#undef SDL_AtomicSetPtr +#endif + +#ifdef SDL_AtomicGetPtr +#undef SDL_AtomicGetPtr +#endif + +#ifdef SDL_GetNumAudioDrivers +#undef SDL_GetNumAudioDrivers +#endif + +#ifdef SDL_GetAudioDriver +#undef SDL_GetAudioDriver +#endif + +#ifdef SDL_AudioInit +#undef SDL_AudioInit +#endif + +#ifdef SDL_AudioQuit +#undef SDL_AudioQuit +#endif + +#ifdef SDL_GetCurrentAudioDriver +#undef SDL_GetCurrentAudioDriver +#endif + +#ifdef SDL_OpenAudio +#undef SDL_OpenAudio +#endif + +#ifdef SDL_GetNumAudioDevices +#undef SDL_GetNumAudioDevices +#endif + +#ifdef SDL_GetAudioDeviceName +#undef SDL_GetAudioDeviceName +#endif + +#ifdef SDL_OpenAudioDevice +#undef SDL_OpenAudioDevice +#endif + +#ifdef SDL_GetAudioStatus +#undef SDL_GetAudioStatus +#endif + +#ifdef SDL_GetAudioDeviceStatus +#undef SDL_GetAudioDeviceStatus +#endif + +#ifdef SDL_PauseAudio +#undef SDL_PauseAudio +#endif + +#ifdef SDL_PauseAudioDevice +#undef SDL_PauseAudioDevice +#endif + +#ifdef SDL_LoadWAV_RW +#undef SDL_LoadWAV_RW +#endif + +#ifdef SDL_FreeWAV +#undef SDL_FreeWAV +#endif + +#ifdef SDL_BuildAudioCVT +#undef SDL_BuildAudioCVT +#endif + +#ifdef SDL_ConvertAudio +#undef SDL_ConvertAudio +#endif + +#ifdef SDL_MixAudio +#undef SDL_MixAudio +#endif + +#ifdef SDL_MixAudioFormat +#undef SDL_MixAudioFormat +#endif + +#ifdef SDL_LockAudio +#undef SDL_LockAudio +#endif + +#ifdef SDL_LockAudioDevice +#undef SDL_LockAudioDevice +#endif + +#ifdef SDL_UnlockAudio +#undef SDL_UnlockAudio +#endif + +#ifdef SDL_UnlockAudioDevice +#undef SDL_UnlockAudioDevice +#endif + +#ifdef SDL_CloseAudio +#undef SDL_CloseAudio +#endif + +#ifdef SDL_CloseAudioDevice +#undef SDL_CloseAudioDevice +#endif + +#ifdef SDL_SetClipboardText +#undef SDL_SetClipboardText +#endif + +#ifdef SDL_GetClipboardText +#undef SDL_GetClipboardText +#endif + +#ifdef SDL_HasClipboardText +#undef SDL_HasClipboardText +#endif + +#ifdef SDL_GetCPUCount +#undef SDL_GetCPUCount +#endif + +#ifdef SDL_GetCPUCacheLineSize +#undef SDL_GetCPUCacheLineSize +#endif + +#ifdef SDL_HasRDTSC +#undef SDL_HasRDTSC +#endif + +#ifdef SDL_HasAltiVec +#undef SDL_HasAltiVec +#endif + +#ifdef SDL_HasMMX +#undef SDL_HasMMX +#endif + +#ifdef SDL_Has3DNow +#undef SDL_Has3DNow +#endif + +#ifdef SDL_HasSSE +#undef SDL_HasSSE +#endif + +#ifdef SDL_HasSSE2 +#undef SDL_HasSSE2 +#endif + +#ifdef SDL_HasSSE3 +#undef SDL_HasSSE3 +#endif + +#ifdef SDL_HasSSE41 +#undef SDL_HasSSE41 +#endif + +#ifdef SDL_HasSSE42 +#undef SDL_HasSSE42 +#endif + +#ifdef SDL_GetSystemRAM +#undef SDL_GetSystemRAM +#endif + +#ifdef SDL_GetError +#undef SDL_GetError +#endif + +#ifdef SDL_ClearError +#undef SDL_ClearError +#endif + +#ifdef SDL_Error +#undef SDL_Error +#endif + +#ifdef SDL_PumpEvents +#undef SDL_PumpEvents +#endif + +#ifdef SDL_PeepEvents +#undef SDL_PeepEvents +#endif + +#ifdef SDL_HasEvent +#undef SDL_HasEvent +#endif + +#ifdef SDL_HasEvents +#undef SDL_HasEvents +#endif + +#ifdef SDL_FlushEvent +#undef SDL_FlushEvent +#endif + +#ifdef SDL_FlushEvents +#undef SDL_FlushEvents +#endif + +#ifdef SDL_PollEvent +#undef SDL_PollEvent +#endif + +#ifdef SDL_WaitEvent +#undef SDL_WaitEvent +#endif + +#ifdef SDL_WaitEventTimeout +#undef SDL_WaitEventTimeout +#endif + +#ifdef SDL_PushEvent +#undef SDL_PushEvent +#endif + +#ifdef SDL_SetEventFilter +#undef SDL_SetEventFilter +#endif + +#ifdef SDL_GetEventFilter +#undef SDL_GetEventFilter +#endif + +#ifdef SDL_AddEventWatch +#undef SDL_AddEventWatch +#endif + +#ifdef SDL_DelEventWatch +#undef SDL_DelEventWatch +#endif + +#ifdef SDL_FilterEvents +#undef SDL_FilterEvents +#endif + +#ifdef SDL_EventState +#undef SDL_EventState +#endif + +#ifdef SDL_RegisterEvents +#undef SDL_RegisterEvents +#endif + +#ifdef SDL_GetBasePath +#undef SDL_GetBasePath +#endif + +#ifdef SDL_GetPrefPath +#undef SDL_GetPrefPath +#endif + +#ifdef SDL_GameControllerAddMapping +#undef SDL_GameControllerAddMapping +#endif + +#ifdef SDL_GameControllerMappingForGUID +#undef SDL_GameControllerMappingForGUID +#endif + +#ifdef SDL_GameControllerMapping +#undef SDL_GameControllerMapping +#endif + +#ifdef SDL_IsGameController +#undef SDL_IsGameController +#endif + +#ifdef SDL_GameControllerNameForIndex +#undef SDL_GameControllerNameForIndex +#endif + +#ifdef SDL_GameControllerOpen +#undef SDL_GameControllerOpen +#endif + +#ifdef SDL_GameControllerName +#undef SDL_GameControllerName +#endif + +#ifdef SDL_GameControllerGetAttached +#undef SDL_GameControllerGetAttached +#endif + +#ifdef SDL_GameControllerGetJoystick +#undef SDL_GameControllerGetJoystick +#endif + +#ifdef SDL_GameControllerEventState +#undef SDL_GameControllerEventState +#endif + +#ifdef SDL_GameControllerUpdate +#undef SDL_GameControllerUpdate +#endif + +#ifdef SDL_GameControllerGetAxisFromString +#undef SDL_GameControllerGetAxisFromString +#endif + +#ifdef SDL_GameControllerGetStringForAxis +#undef SDL_GameControllerGetStringForAxis +#endif + +#ifdef SDL_GameControllerGetBindForAxis +#undef SDL_GameControllerGetBindForAxis +#endif + +#ifdef SDL_GameControllerGetAxis +#undef SDL_GameControllerGetAxis +#endif + +#ifdef SDL_GameControllerGetButtonFromString +#undef SDL_GameControllerGetButtonFromString +#endif + +#ifdef SDL_GameControllerGetStringForButton +#undef SDL_GameControllerGetStringForButton +#endif + +#ifdef SDL_GameControllerGetBindForButton +#undef SDL_GameControllerGetBindForButton +#endif + +#ifdef SDL_GameControllerGetButton +#undef SDL_GameControllerGetButton +#endif + +#ifdef SDL_GameControllerClose +#undef SDL_GameControllerClose +#endif + +#ifdef SDL_RecordGesture +#undef SDL_RecordGesture +#endif + +#ifdef SDL_SaveAllDollarTemplates +#undef SDL_SaveAllDollarTemplates +#endif + +#ifdef SDL_SaveDollarTemplate +#undef SDL_SaveDollarTemplate +#endif + +#ifdef SDL_LoadDollarTemplates +#undef SDL_LoadDollarTemplates +#endif + +#ifdef SDL_NumHaptics +#undef SDL_NumHaptics +#endif + +#ifdef SDL_HapticName +#undef SDL_HapticName +#endif + +#ifdef SDL_HapticOpen +#undef SDL_HapticOpen +#endif + +#ifdef SDL_HapticOpened +#undef SDL_HapticOpened +#endif + +#ifdef SDL_HapticIndex +#undef SDL_HapticIndex +#endif + +#ifdef SDL_MouseIsHaptic +#undef SDL_MouseIsHaptic +#endif + +#ifdef SDL_HapticOpenFromMouse +#undef SDL_HapticOpenFromMouse +#endif + +#ifdef SDL_JoystickIsHaptic +#undef SDL_JoystickIsHaptic +#endif + +#ifdef SDL_HapticOpenFromJoystick +#undef SDL_HapticOpenFromJoystick +#endif + +#ifdef SDL_HapticClose +#undef SDL_HapticClose +#endif + +#ifdef SDL_HapticNumEffects +#undef SDL_HapticNumEffects +#endif + +#ifdef SDL_HapticNumEffectsPlaying +#undef SDL_HapticNumEffectsPlaying +#endif + +#ifdef SDL_HapticQuery +#undef SDL_HapticQuery +#endif + +#ifdef SDL_HapticNumAxes +#undef SDL_HapticNumAxes +#endif + +#ifdef SDL_HapticEffectSupported +#undef SDL_HapticEffectSupported +#endif + +#ifdef SDL_HapticNewEffect +#undef SDL_HapticNewEffect +#endif + +#ifdef SDL_HapticUpdateEffect +#undef SDL_HapticUpdateEffect +#endif + +#ifdef SDL_HapticRunEffect +#undef SDL_HapticRunEffect +#endif + +#ifdef SDL_HapticStopEffect +#undef SDL_HapticStopEffect +#endif + +#ifdef SDL_HapticDestroyEffect +#undef SDL_HapticDestroyEffect +#endif + +#ifdef SDL_HapticGetEffectStatus +#undef SDL_HapticGetEffectStatus +#endif + +#ifdef SDL_HapticSetGain +#undef SDL_HapticSetGain +#endif + +#ifdef SDL_HapticSetAutocenter +#undef SDL_HapticSetAutocenter +#endif + +#ifdef SDL_HapticPause +#undef SDL_HapticPause +#endif + +#ifdef SDL_HapticUnpause +#undef SDL_HapticUnpause +#endif + +#ifdef SDL_HapticStopAll +#undef SDL_HapticStopAll +#endif + +#ifdef SDL_HapticRumbleSupported +#undef SDL_HapticRumbleSupported +#endif + +#ifdef SDL_HapticRumbleInit +#undef SDL_HapticRumbleInit +#endif + +#ifdef SDL_HapticRumblePlay +#undef SDL_HapticRumblePlay +#endif + +#ifdef SDL_HapticRumbleStop +#undef SDL_HapticRumbleStop +#endif + +#ifdef SDL_SetHintWithPriority +#undef SDL_SetHintWithPriority +#endif + +#ifdef SDL_SetHint +#undef SDL_SetHint +#endif + +#ifdef SDL_GetHint +#undef SDL_GetHint +#endif + +#ifdef SDL_AddHintCallback +#undef SDL_AddHintCallback +#endif + +#ifdef SDL_DelHintCallback +#undef SDL_DelHintCallback +#endif + +#ifdef SDL_ClearHints +#undef SDL_ClearHints +#endif + +#ifdef SDL_NumJoysticks +#undef SDL_NumJoysticks +#endif + +#ifdef SDL_JoystickNameForIndex +#undef SDL_JoystickNameForIndex +#endif + +#ifdef SDL_JoystickOpen +#undef SDL_JoystickOpen +#endif + +#ifdef SDL_JoystickName +#undef SDL_JoystickName +#endif + +#ifdef SDL_JoystickGetDeviceGUID +#undef SDL_JoystickGetDeviceGUID +#endif + +#ifdef SDL_JoystickGetGUID +#undef SDL_JoystickGetGUID +#endif + +#ifdef SDL_JoystickGetGUIDString +#undef SDL_JoystickGetGUIDString +#endif + +#ifdef SDL_JoystickGetGUIDFromString +#undef SDL_JoystickGetGUIDFromString +#endif + +#ifdef SDL_JoystickGetAttached +#undef SDL_JoystickGetAttached +#endif + +#ifdef SDL_JoystickInstanceID +#undef SDL_JoystickInstanceID +#endif + +#ifdef SDL_JoystickNumAxes +#undef SDL_JoystickNumAxes +#endif + +#ifdef SDL_JoystickNumBalls +#undef SDL_JoystickNumBalls +#endif + +#ifdef SDL_JoystickNumHats +#undef SDL_JoystickNumHats +#endif + +#ifdef SDL_JoystickNumButtons +#undef SDL_JoystickNumButtons +#endif + +#ifdef SDL_JoystickUpdate +#undef SDL_JoystickUpdate +#endif + +#ifdef SDL_JoystickEventState +#undef SDL_JoystickEventState +#endif + +#ifdef SDL_JoystickGetAxis +#undef SDL_JoystickGetAxis +#endif + +#ifdef SDL_JoystickGetHat +#undef SDL_JoystickGetHat +#endif + +#ifdef SDL_JoystickGetBall +#undef SDL_JoystickGetBall +#endif + +#ifdef SDL_JoystickGetButton +#undef SDL_JoystickGetButton +#endif + +#ifdef SDL_JoystickClose +#undef SDL_JoystickClose +#endif + +#ifdef SDL_GetKeyboardFocus +#undef SDL_GetKeyboardFocus +#endif + +#ifdef SDL_GetKeyboardState +#undef SDL_GetKeyboardState +#endif + +#ifdef SDL_GetModState +#undef SDL_GetModState +#endif + +#ifdef SDL_SetModState +#undef SDL_SetModState +#endif + +#ifdef SDL_GetKeyFromScancode +#undef SDL_GetKeyFromScancode +#endif + +#ifdef SDL_GetScancodeFromKey +#undef SDL_GetScancodeFromKey +#endif + +#ifdef SDL_GetScancodeName +#undef SDL_GetScancodeName +#endif + +#ifdef SDL_GetScancodeFromName +#undef SDL_GetScancodeFromName +#endif + +#ifdef SDL_GetKeyName +#undef SDL_GetKeyName +#endif + +#ifdef SDL_GetKeyFromName +#undef SDL_GetKeyFromName +#endif + +#ifdef SDL_StartTextInput +#undef SDL_StartTextInput +#endif + +#ifdef SDL_IsTextInputActive +#undef SDL_IsTextInputActive +#endif + +#ifdef SDL_StopTextInput +#undef SDL_StopTextInput +#endif + +#ifdef SDL_SetTextInputRect +#undef SDL_SetTextInputRect +#endif + +#ifdef SDL_HasScreenKeyboardSupport +#undef SDL_HasScreenKeyboardSupport +#endif + +#ifdef SDL_IsScreenKeyboardShown +#undef SDL_IsScreenKeyboardShown +#endif + +#ifdef SDL_LoadObject +#undef SDL_LoadObject +#endif + +#ifdef SDL_LoadFunction +#undef SDL_LoadFunction +#endif + +#ifdef SDL_UnloadObject +#undef SDL_UnloadObject +#endif + +#ifdef SDL_LogSetAllPriority +#undef SDL_LogSetAllPriority +#endif + +#ifdef SDL_LogSetPriority +#undef SDL_LogSetPriority +#endif + +#ifdef SDL_LogGetPriority +#undef SDL_LogGetPriority +#endif + +#ifdef SDL_LogResetPriorities +#undef SDL_LogResetPriorities +#endif + +#ifdef SDL_LogMessageV +#undef SDL_LogMessageV +#endif + +#ifdef SDL_LogGetOutputFunction +#undef SDL_LogGetOutputFunction +#endif + +#ifdef SDL_LogSetOutputFunction +#undef SDL_LogSetOutputFunction +#endif + +#ifdef SDL_SetMainReady +#undef SDL_SetMainReady +#endif + +#ifdef SDL_ShowMessageBox +#undef SDL_ShowMessageBox +#endif + +#ifdef SDL_ShowSimpleMessageBox +#undef SDL_ShowSimpleMessageBox +#endif + +#ifdef SDL_GetMouseFocus +#undef SDL_GetMouseFocus +#endif + +#ifdef SDL_GetMouseState +#undef SDL_GetMouseState +#endif + +#ifdef SDL_GetRelativeMouseState +#undef SDL_GetRelativeMouseState +#endif + +#ifdef SDL_WarpMouseInWindow +#undef SDL_WarpMouseInWindow +#endif + +#ifdef SDL_SetRelativeMouseMode +#undef SDL_SetRelativeMouseMode +#endif + +#ifdef SDL_GetRelativeMouseMode +#undef SDL_GetRelativeMouseMode +#endif + +#ifdef SDL_CreateCursor +#undef SDL_CreateCursor +#endif + +#ifdef SDL_CreateColorCursor +#undef SDL_CreateColorCursor +#endif + +#ifdef SDL_CreateSystemCursor +#undef SDL_CreateSystemCursor +#endif + +#ifdef SDL_SetCursor +#undef SDL_SetCursor +#endif + +#ifdef SDL_GetCursor +#undef SDL_GetCursor +#endif + +#ifdef SDL_GetDefaultCursor +#undef SDL_GetDefaultCursor +#endif + +#ifdef SDL_FreeCursor +#undef SDL_FreeCursor +#endif + +#ifdef SDL_ShowCursor +#undef SDL_ShowCursor +#endif + +#ifdef SDL_CreateMutex +#undef SDL_CreateMutex +#endif + +#ifdef SDL_LockMutex +#undef SDL_LockMutex +#endif + +#ifdef SDL_TryLockMutex +#undef SDL_TryLockMutex +#endif + +#ifdef SDL_UnlockMutex +#undef SDL_UnlockMutex +#endif + +#ifdef SDL_DestroyMutex +#undef SDL_DestroyMutex +#endif + +#ifdef SDL_CreateSemaphore +#undef SDL_CreateSemaphore +#endif + +#ifdef SDL_DestroySemaphore +#undef SDL_DestroySemaphore +#endif + +#ifdef SDL_SemWait +#undef SDL_SemWait +#endif + +#ifdef SDL_SemTryWait +#undef SDL_SemTryWait +#endif + +#ifdef SDL_SemWaitTimeout +#undef SDL_SemWaitTimeout +#endif + +#ifdef SDL_SemPost +#undef SDL_SemPost +#endif + +#ifdef SDL_SemValue +#undef SDL_SemValue +#endif + +#ifdef SDL_CreateCond +#undef SDL_CreateCond +#endif + +#ifdef SDL_DestroyCond +#undef SDL_DestroyCond +#endif + +#ifdef SDL_CondSignal +#undef SDL_CondSignal +#endif + +#ifdef SDL_CondBroadcast +#undef SDL_CondBroadcast +#endif + +#ifdef SDL_CondWait +#undef SDL_CondWait +#endif + +#ifdef SDL_CondWaitTimeout +#undef SDL_CondWaitTimeout +#endif + +#ifdef SDL_GetPixelFormatName +#undef SDL_GetPixelFormatName +#endif + +#ifdef SDL_PixelFormatEnumToMasks +#undef SDL_PixelFormatEnumToMasks +#endif + +#ifdef SDL_MasksToPixelFormatEnum +#undef SDL_MasksToPixelFormatEnum +#endif + +#ifdef SDL_AllocFormat +#undef SDL_AllocFormat +#endif + +#ifdef SDL_FreeFormat +#undef SDL_FreeFormat +#endif + +#ifdef SDL_AllocPalette +#undef SDL_AllocPalette +#endif + +#ifdef SDL_SetPixelFormatPalette +#undef SDL_SetPixelFormatPalette +#endif + +#ifdef SDL_SetPaletteColors +#undef SDL_SetPaletteColors +#endif + +#ifdef SDL_FreePalette +#undef SDL_FreePalette +#endif + +#ifdef SDL_MapRGB +#undef SDL_MapRGB +#endif + +#ifdef SDL_MapRGBA +#undef SDL_MapRGBA +#endif + +#ifdef SDL_GetRGB +#undef SDL_GetRGB +#endif + +#ifdef SDL_GetRGBA +#undef SDL_GetRGBA +#endif + +#ifdef SDL_CalculateGammaRamp +#undef SDL_CalculateGammaRamp +#endif + +#ifdef SDL_GetPlatform +#undef SDL_GetPlatform +#endif + +#ifdef SDL_GetPowerInfo +#undef SDL_GetPowerInfo +#endif + +#ifdef SDL_HasIntersection +#undef SDL_HasIntersection +#endif + +#ifdef SDL_IntersectRect +#undef SDL_IntersectRect +#endif + +#ifdef SDL_UnionRect +#undef SDL_UnionRect +#endif + +#ifdef SDL_EnclosePoints +#undef SDL_EnclosePoints +#endif + +#ifdef SDL_IntersectRectAndLine +#undef SDL_IntersectRectAndLine +#endif + +#ifdef SDL_GetNumRenderDrivers +#undef SDL_GetNumRenderDrivers +#endif + +#ifdef SDL_GetRenderDriverInfo +#undef SDL_GetRenderDriverInfo +#endif + +#ifdef SDL_CreateWindowAndRenderer +#undef SDL_CreateWindowAndRenderer +#endif + +#ifdef SDL_CreateRenderer +#undef SDL_CreateRenderer +#endif + +#ifdef SDL_CreateSoftwareRenderer +#undef SDL_CreateSoftwareRenderer +#endif + +#ifdef SDL_GetRenderer +#undef SDL_GetRenderer +#endif + +#ifdef SDL_GetRendererInfo +#undef SDL_GetRendererInfo +#endif + +#ifdef SDL_GetRendererOutputSize +#undef SDL_GetRendererOutputSize +#endif + +#ifdef SDL_CreateTexture +#undef SDL_CreateTexture +#endif + +#ifdef SDL_CreateTextureFromSurface +#undef SDL_CreateTextureFromSurface +#endif + +#ifdef SDL_QueryTexture +#undef SDL_QueryTexture +#endif + +#ifdef SDL_SetTextureColorMod +#undef SDL_SetTextureColorMod +#endif + +#ifdef SDL_GetTextureColorMod +#undef SDL_GetTextureColorMod +#endif + +#ifdef SDL_SetTextureAlphaMod +#undef SDL_SetTextureAlphaMod +#endif + +#ifdef SDL_GetTextureAlphaMod +#undef SDL_GetTextureAlphaMod +#endif + +#ifdef SDL_SetTextureBlendMode +#undef SDL_SetTextureBlendMode +#endif + +#ifdef SDL_GetTextureBlendMode +#undef SDL_GetTextureBlendMode +#endif + +#ifdef SDL_UpdateTexture +#undef SDL_UpdateTexture +#endif + +#ifdef SDL_UpdateYUVTexture +#undef SDL_UpdateYUVTexture +#endif + +#ifdef SDL_LockTexture +#undef SDL_LockTexture +#endif + +#ifdef SDL_UnlockTexture +#undef SDL_UnlockTexture +#endif + +#ifdef SDL_RenderTargetSupported +#undef SDL_RenderTargetSupported +#endif + +#ifdef SDL_SetRenderTarget +#undef SDL_SetRenderTarget +#endif + +#ifdef SDL_GetRenderTarget +#undef SDL_GetRenderTarget +#endif + +#ifdef SDL_RenderSetLogicalSize +#undef SDL_RenderSetLogicalSize +#endif + +#ifdef SDL_RenderGetLogicalSize +#undef SDL_RenderGetLogicalSize +#endif + +#ifdef SDL_RenderSetViewport +#undef SDL_RenderSetViewport +#endif + +#ifdef SDL_RenderGetViewport +#undef SDL_RenderGetViewport +#endif + +#ifdef SDL_RenderSetClipRect +#undef SDL_RenderSetClipRect +#endif + +#ifdef SDL_RenderGetClipRect +#undef SDL_RenderGetClipRect +#endif + +#ifdef SDL_RenderSetScale +#undef SDL_RenderSetScale +#endif + +#ifdef SDL_RenderGetScale +#undef SDL_RenderGetScale +#endif + +#ifdef SDL_SetRenderDrawColor +#undef SDL_SetRenderDrawColor +#endif + +#ifdef SDL_GetRenderDrawColor +#undef SDL_GetRenderDrawColor +#endif + +#ifdef SDL_SetRenderDrawBlendMode +#undef SDL_SetRenderDrawBlendMode +#endif + +#ifdef SDL_GetRenderDrawBlendMode +#undef SDL_GetRenderDrawBlendMode +#endif + +#ifdef SDL_RenderClear +#undef SDL_RenderClear +#endif + +#ifdef SDL_RenderDrawPoint +#undef SDL_RenderDrawPoint +#endif + +#ifdef SDL_RenderDrawPoints +#undef SDL_RenderDrawPoints +#endif + +#ifdef SDL_RenderDrawLine +#undef SDL_RenderDrawLine +#endif + +#ifdef SDL_RenderDrawLines +#undef SDL_RenderDrawLines +#endif + +#ifdef SDL_RenderDrawRect +#undef SDL_RenderDrawRect +#endif + +#ifdef SDL_RenderDrawRects +#undef SDL_RenderDrawRects +#endif + +#ifdef SDL_RenderFillRect +#undef SDL_RenderFillRect +#endif + +#ifdef SDL_RenderFillRects +#undef SDL_RenderFillRects +#endif + +#ifdef SDL_RenderCopy +#undef SDL_RenderCopy +#endif + +#ifdef SDL_RenderCopyEx +#undef SDL_RenderCopyEx +#endif + +#ifdef SDL_RenderReadPixels +#undef SDL_RenderReadPixels +#endif + +#ifdef SDL_RenderPresent +#undef SDL_RenderPresent +#endif + +#ifdef SDL_DestroyTexture +#undef SDL_DestroyTexture +#endif + +#ifdef SDL_DestroyRenderer +#undef SDL_DestroyRenderer +#endif + +#ifdef SDL_GL_BindTexture +#undef SDL_GL_BindTexture +#endif + +#ifdef SDL_GL_UnbindTexture +#undef SDL_GL_UnbindTexture +#endif + +#ifdef SDL_RWFromFile +#undef SDL_RWFromFile +#endif + +#ifdef SDL_RWFromMem +#undef SDL_RWFromMem +#endif + +#ifdef SDL_RWFromConstMem +#undef SDL_RWFromConstMem +#endif + +#ifdef SDL_AllocRW +#undef SDL_AllocRW +#endif + +#ifdef SDL_FreeRW +#undef SDL_FreeRW +#endif + +#ifdef SDL_ReadU8 +#undef SDL_ReadU8 +#endif + +#ifdef SDL_ReadLE16 +#undef SDL_ReadLE16 +#endif + +#ifdef SDL_ReadBE16 +#undef SDL_ReadBE16 +#endif + +#ifdef SDL_ReadLE32 +#undef SDL_ReadLE32 +#endif + +#ifdef SDL_ReadBE32 +#undef SDL_ReadBE32 +#endif + +#ifdef SDL_ReadLE64 +#undef SDL_ReadLE64 +#endif + +#ifdef SDL_ReadBE64 +#undef SDL_ReadBE64 +#endif + +#ifdef SDL_WriteU8 +#undef SDL_WriteU8 +#endif + +#ifdef SDL_WriteLE16 +#undef SDL_WriteLE16 +#endif + +#ifdef SDL_WriteBE16 +#undef SDL_WriteBE16 +#endif + +#ifdef SDL_WriteLE32 +#undef SDL_WriteLE32 +#endif + +#ifdef SDL_WriteBE32 +#undef SDL_WriteBE32 +#endif + +#ifdef SDL_WriteLE64 +#undef SDL_WriteLE64 +#endif + +#ifdef SDL_WriteBE64 +#undef SDL_WriteBE64 +#endif + +#ifdef SDL_CreateShapedWindow +#undef SDL_CreateShapedWindow +#endif + +#ifdef SDL_IsShapedWindow +#undef SDL_IsShapedWindow +#endif + +#ifdef SDL_SetWindowShape +#undef SDL_SetWindowShape +#endif + +#ifdef SDL_GetShapedWindowMode +#undef SDL_GetShapedWindowMode +#endif + +#ifdef SDL_malloc +#undef SDL_malloc +#endif + +#ifdef SDL_calloc +#undef SDL_calloc +#endif + +#ifdef SDL_realloc +#undef SDL_realloc +#endif + +#ifdef SDL_free +#undef SDL_free +#endif + +#ifdef SDL_getenv +#undef SDL_getenv +#endif + +#ifdef SDL_setenv +#undef SDL_setenv +#endif + +#ifdef SDL_qsort +#undef SDL_qsort +#endif + +#ifdef SDL_abs +#undef SDL_abs +#endif + +#ifdef SDL_isdigit +#undef SDL_isdigit +#endif + +#ifdef SDL_isspace +#undef SDL_isspace +#endif + +#ifdef SDL_toupper +#undef SDL_toupper +#endif + +#ifdef SDL_tolower +#undef SDL_tolower +#endif + +#ifdef SDL_memset +#undef SDL_memset +#endif + +#ifdef SDL_memcpy +#undef SDL_memcpy +#endif + +#ifdef SDL_memmove +#undef SDL_memmove +#endif + +#ifdef SDL_memcmp +#undef SDL_memcmp +#endif + +#ifdef SDL_wcslen +#undef SDL_wcslen +#endif + +#ifdef SDL_wcslcpy +#undef SDL_wcslcpy +#endif + +#ifdef SDL_wcslcat +#undef SDL_wcslcat +#endif + +#ifdef SDL_strlen +#undef SDL_strlen +#endif + +#ifdef SDL_strlcpy +#undef SDL_strlcpy +#endif + +#ifdef SDL_utf8strlcpy +#undef SDL_utf8strlcpy +#endif + +#ifdef SDL_strlcat +#undef SDL_strlcat +#endif + +#ifdef SDL_strdup +#undef SDL_strdup +#endif + +#ifdef SDL_strrev +#undef SDL_strrev +#endif + +#ifdef SDL_strupr +#undef SDL_strupr +#endif + +#ifdef SDL_strlwr +#undef SDL_strlwr +#endif + +#ifdef SDL_strchr +#undef SDL_strchr +#endif + +#ifdef SDL_strrchr +#undef SDL_strrchr +#endif + +#ifdef SDL_strstr +#undef SDL_strstr +#endif + +#ifdef SDL_itoa +#undef SDL_itoa +#endif + +#ifdef SDL_uitoa +#undef SDL_uitoa +#endif + +#ifdef SDL_ltoa +#undef SDL_ltoa +#endif + +#ifdef SDL_ultoa +#undef SDL_ultoa +#endif + +#ifdef SDL_lltoa +#undef SDL_lltoa +#endif + +#ifdef SDL_ulltoa +#undef SDL_ulltoa +#endif + +#ifdef SDL_atoi +#undef SDL_atoi +#endif + +#ifdef SDL_atof +#undef SDL_atof +#endif + +#ifdef SDL_strtol +#undef SDL_strtol +#endif + +#ifdef SDL_strtoul +#undef SDL_strtoul +#endif + +#ifdef SDL_strtoll +#undef SDL_strtoll #endif #ifdef SDL_strtoull #undef SDL_strtoull #endif -#ifdef SDL_strtod -#undef SDL_strtod +#ifdef SDL_strtod +#undef SDL_strtod +#endif + +#ifdef SDL_strcmp +#undef SDL_strcmp +#endif + +#ifdef SDL_strncmp +#undef SDL_strncmp +#endif + +#ifdef SDL_strcasecmp +#undef SDL_strcasecmp +#endif + +#ifdef SDL_strncasecmp +#undef SDL_strncasecmp +#endif + +#ifdef SDL_vsnprintf +#undef SDL_vsnprintf +#endif + +#ifdef SDL_acos +#undef SDL_acos +#endif + +#ifdef SDL_asin +#undef SDL_asin +#endif + +#ifdef SDL_atan +#undef SDL_atan +#endif + +#ifdef SDL_atan2 +#undef SDL_atan2 +#endif + +#ifdef SDL_ceil +#undef SDL_ceil +#endif + +#ifdef SDL_copysign +#undef SDL_copysign +#endif + +#ifdef SDL_cos +#undef SDL_cos +#endif + +#ifdef SDL_cosf +#undef SDL_cosf +#endif + +#ifdef SDL_fabs +#undef SDL_fabs +#endif + +#ifdef SDL_floor +#undef SDL_floor +#endif + +#ifdef SDL_log +#undef SDL_log +#endif + +#ifdef SDL_pow +#undef SDL_pow +#endif + +#ifdef SDL_scalbn +#undef SDL_scalbn +#endif + +#ifdef SDL_sin +#undef SDL_sin +#endif + +#ifdef SDL_sinf +#undef SDL_sinf +#endif + +#ifdef SDL_sqrt +#undef SDL_sqrt +#endif + +#ifdef SDL_iconv_open +#undef SDL_iconv_open +#endif + +#ifdef SDL_iconv_close +#undef SDL_iconv_close +#endif + +#ifdef SDL_iconv +#undef SDL_iconv +#endif + +#ifdef SDL_iconv_string +#undef SDL_iconv_string +#endif + +#ifdef SDL_CreateRGBSurface +#undef SDL_CreateRGBSurface +#endif + +#ifdef SDL_CreateRGBSurfaceFrom +#undef SDL_CreateRGBSurfaceFrom +#endif + +#ifdef SDL_FreeSurface +#undef SDL_FreeSurface +#endif + +#ifdef SDL_SetSurfacePalette +#undef SDL_SetSurfacePalette +#endif + +#ifdef SDL_LockSurface +#undef SDL_LockSurface +#endif + +#ifdef SDL_UnlockSurface +#undef SDL_UnlockSurface +#endif + +#ifdef SDL_LoadBMP_RW +#undef SDL_LoadBMP_RW +#endif + +#ifdef SDL_SaveBMP_RW +#undef SDL_SaveBMP_RW +#endif + +#ifdef SDL_SetSurfaceRLE +#undef SDL_SetSurfaceRLE +#endif + +#ifdef SDL_SetColorKey +#undef SDL_SetColorKey +#endif + +#ifdef SDL_GetColorKey +#undef SDL_GetColorKey +#endif + +#ifdef SDL_SetSurfaceColorMod +#undef SDL_SetSurfaceColorMod +#endif + +#ifdef SDL_GetSurfaceColorMod +#undef SDL_GetSurfaceColorMod +#endif + +#ifdef SDL_SetSurfaceAlphaMod +#undef SDL_SetSurfaceAlphaMod +#endif + +#ifdef SDL_GetSurfaceAlphaMod +#undef SDL_GetSurfaceAlphaMod +#endif + +#ifdef SDL_SetSurfaceBlendMode +#undef SDL_SetSurfaceBlendMode +#endif + +#ifdef SDL_GetSurfaceBlendMode +#undef SDL_GetSurfaceBlendMode +#endif + +#ifdef SDL_SetClipRect +#undef SDL_SetClipRect +#endif + +#ifdef SDL_GetClipRect +#undef SDL_GetClipRect +#endif + +#ifdef SDL_ConvertSurface +#undef SDL_ConvertSurface +#endif + +#ifdef SDL_ConvertSurfaceFormat +#undef SDL_ConvertSurfaceFormat +#endif + +#ifdef SDL_ConvertPixels +#undef SDL_ConvertPixels +#endif + +#ifdef SDL_FillRect +#undef SDL_FillRect +#endif + +#ifdef SDL_FillRects +#undef SDL_FillRects +#endif + +#ifdef SDL_UpperBlit +#undef SDL_UpperBlit +#endif + +#ifdef SDL_LowerBlit +#undef SDL_LowerBlit +#endif + +#ifdef SDL_SoftStretch +#undef SDL_SoftStretch +#endif + +#ifdef SDL_UpperBlitScaled +#undef SDL_UpperBlitScaled +#endif + +#ifdef SDL_LowerBlitScaled +#undef SDL_LowerBlitScaled +#endif + +#ifdef SDL_GetWindowWMInfo +#undef SDL_GetWindowWMInfo +#endif + +#ifdef SDL_GetThreadName +#undef SDL_GetThreadName +#endif + +#ifdef SDL_ThreadID +#undef SDL_ThreadID +#endif + +#ifdef SDL_GetThreadID +#undef SDL_GetThreadID +#endif + +#ifdef SDL_SetThreadPriority +#undef SDL_SetThreadPriority +#endif + +#ifdef SDL_WaitThread +#undef SDL_WaitThread +#endif + +#ifdef SDL_DetachThread +#undef SDL_DetachThread +#endif + +#ifdef SDL_TLSCreate +#undef SDL_TLSCreate +#endif + +#ifdef SDL_TLSGet +#undef SDL_TLSGet +#endif + +#ifdef SDL_TLSSet +#undef SDL_TLSSet +#endif + +#ifdef SDL_GetTicks +#undef SDL_GetTicks +#endif + +#ifdef SDL_GetPerformanceCounter +#undef SDL_GetPerformanceCounter +#endif + +#ifdef SDL_GetPerformanceFrequency +#undef SDL_GetPerformanceFrequency +#endif + +#ifdef SDL_Delay +#undef SDL_Delay +#endif + +#ifdef SDL_AddTimer +#undef SDL_AddTimer +#endif + +#ifdef SDL_RemoveTimer +#undef SDL_RemoveTimer +#endif + +#ifdef SDL_GetNumTouchDevices +#undef SDL_GetNumTouchDevices +#endif + +#ifdef SDL_GetTouchDevice +#undef SDL_GetTouchDevice +#endif + +#ifdef SDL_GetNumTouchFingers +#undef SDL_GetNumTouchFingers +#endif + +#ifdef SDL_GetTouchFinger +#undef SDL_GetTouchFinger +#endif + +#ifdef SDL_GetVersion +#undef SDL_GetVersion +#endif + +#ifdef SDL_GetRevision +#undef SDL_GetRevision +#endif + +#ifdef SDL_GetRevisionNumber +#undef SDL_GetRevisionNumber +#endif + +#ifdef SDL_GetNumVideoDrivers +#undef SDL_GetNumVideoDrivers +#endif + +#ifdef SDL_GetVideoDriver +#undef SDL_GetVideoDriver +#endif + +#ifdef SDL_VideoInit +#undef SDL_VideoInit +#endif + +#ifdef SDL_VideoQuit +#undef SDL_VideoQuit +#endif + +#ifdef SDL_GetCurrentVideoDriver +#undef SDL_GetCurrentVideoDriver +#endif + +#ifdef SDL_GetNumVideoDisplays +#undef SDL_GetNumVideoDisplays +#endif + +#ifdef SDL_GetDisplayName +#undef SDL_GetDisplayName +#endif + +#ifdef SDL_GetDisplayBounds +#undef SDL_GetDisplayBounds +#endif + +#ifdef SDL_GetDisplayDPI +#undef SDL_GetDisplayDPI +#endif + +#ifdef SDL_GetNumDisplayModes +#undef SDL_GetNumDisplayModes +#endif + +#ifdef SDL_GetDisplayMode +#undef SDL_GetDisplayMode +#endif + +#ifdef SDL_GetDesktopDisplayMode +#undef SDL_GetDesktopDisplayMode +#endif + +#ifdef SDL_GetCurrentDisplayMode +#undef SDL_GetCurrentDisplayMode +#endif + +#ifdef SDL_GetClosestDisplayMode +#undef SDL_GetClosestDisplayMode +#endif + +#ifdef SDL_GetWindowDisplayIndex +#undef SDL_GetWindowDisplayIndex +#endif + +#ifdef SDL_SetWindowDisplayMode +#undef SDL_SetWindowDisplayMode +#endif + +#ifdef SDL_GetWindowDisplayMode +#undef SDL_GetWindowDisplayMode +#endif + +#ifdef SDL_GetWindowPixelFormat +#undef SDL_GetWindowPixelFormat +#endif + +#ifdef SDL_CreateWindow +#undef SDL_CreateWindow +#endif + +#ifdef SDL_CreateWindowFrom +#undef SDL_CreateWindowFrom +#endif + +#ifdef SDL_GetWindowID +#undef SDL_GetWindowID +#endif + +#ifdef SDL_GetWindowFromID +#undef SDL_GetWindowFromID +#endif + +#ifdef SDL_GetWindowFlags +#undef SDL_GetWindowFlags +#endif + +#ifdef SDL_SetWindowTitle +#undef SDL_SetWindowTitle +#endif + +#ifdef SDL_GetWindowTitle +#undef SDL_GetWindowTitle +#endif + +#ifdef SDL_SetWindowIcon +#undef SDL_SetWindowIcon +#endif + +#ifdef SDL_SetWindowData +#undef SDL_SetWindowData +#endif + +#ifdef SDL_GetWindowData +#undef SDL_GetWindowData +#endif + +#ifdef SDL_SetWindowPosition +#undef SDL_SetWindowPosition +#endif + +#ifdef SDL_GetWindowPosition +#undef SDL_GetWindowPosition +#endif + +#ifdef SDL_SetWindowSize +#undef SDL_SetWindowSize +#endif + +#ifdef SDL_GetWindowSize +#undef SDL_GetWindowSize +#endif + +#ifdef SDL_SetWindowMinimumSize +#undef SDL_SetWindowMinimumSize +#endif + +#ifdef SDL_GetWindowMinimumSize +#undef SDL_GetWindowMinimumSize +#endif + +#ifdef SDL_SetWindowMaximumSize +#undef SDL_SetWindowMaximumSize +#endif + +#ifdef SDL_GetWindowMaximumSize +#undef SDL_GetWindowMaximumSize +#endif + +#ifdef SDL_SetWindowBordered +#undef SDL_SetWindowBordered +#endif + +#ifdef SDL_ShowWindow +#undef SDL_ShowWindow +#endif + +#ifdef SDL_HideWindow +#undef SDL_HideWindow +#endif + +#ifdef SDL_RaiseWindow +#undef SDL_RaiseWindow +#endif + +#ifdef SDL_MaximizeWindow +#undef SDL_MaximizeWindow +#endif + +#ifdef SDL_MinimizeWindow +#undef SDL_MinimizeWindow +#endif + +#ifdef SDL_RestoreWindow +#undef SDL_RestoreWindow +#endif + +#ifdef SDL_SetWindowFullscreen +#undef SDL_SetWindowFullscreen +#endif + +#ifdef SDL_GetWindowSurface +#undef SDL_GetWindowSurface +#endif + +#ifdef SDL_UpdateWindowSurface +#undef SDL_UpdateWindowSurface +#endif + +#ifdef SDL_UpdateWindowSurfaceRects +#undef SDL_UpdateWindowSurfaceRects +#endif + +#ifdef SDL_SetWindowGrab +#undef SDL_SetWindowGrab +#endif + +#ifdef SDL_GetWindowGrab +#undef SDL_GetWindowGrab +#endif + +#ifdef SDL_SetWindowBrightness +#undef SDL_SetWindowBrightness +#endif + +#ifdef SDL_GetWindowBrightness +#undef SDL_GetWindowBrightness +#endif + +#ifdef SDL_SetWindowGammaRamp +#undef SDL_SetWindowGammaRamp +#endif + +#ifdef SDL_GetWindowGammaRamp +#undef SDL_GetWindowGammaRamp +#endif + +#ifdef SDL_DestroyWindow +#undef SDL_DestroyWindow +#endif + +#ifdef SDL_IsScreenSaverEnabled +#undef SDL_IsScreenSaverEnabled +#endif + +#ifdef SDL_EnableScreenSaver +#undef SDL_EnableScreenSaver +#endif + +#ifdef SDL_DisableScreenSaver +#undef SDL_DisableScreenSaver +#endif + +#ifdef SDL_GL_LoadLibrary +#undef SDL_GL_LoadLibrary +#endif + +#ifdef SDL_GL_GetProcAddress +#undef SDL_GL_GetProcAddress +#endif + +#ifdef SDL_GL_UnloadLibrary +#undef SDL_GL_UnloadLibrary +#endif + +#ifdef SDL_GL_ExtensionSupported +#undef SDL_GL_ExtensionSupported +#endif + +#ifdef SDL_GL_SetAttribute +#undef SDL_GL_SetAttribute +#endif + +#ifdef SDL_GL_GetAttribute +#undef SDL_GL_GetAttribute +#endif + +#ifdef SDL_GL_CreateContext +#undef SDL_GL_CreateContext +#endif + +#ifdef SDL_GL_MakeCurrent +#undef SDL_GL_MakeCurrent +#endif + +#ifdef SDL_GL_GetCurrentWindow +#undef SDL_GL_GetCurrentWindow +#endif + +#ifdef SDL_GL_GetCurrentContext +#undef SDL_GL_GetCurrentContext +#endif + +#ifdef SDL_GL_GetDrawableSize +#undef SDL_GL_GetDrawableSize +#endif + +#ifdef SDL_GL_SetSwapInterval +#undef SDL_GL_SetSwapInterval +#endif + +#ifdef SDL_GL_GetSwapInterval +#undef SDL_GL_GetSwapInterval +#endif + +#ifdef SDL_GL_SwapWindow +#undef SDL_GL_SwapWindow +#endif + +#ifdef SDL_GL_DeleteContext +#undef SDL_GL_DeleteContext +#endif + +#ifdef SDL_vsscanf +#undef SDL_vsscanf +#endif + +#ifdef SDL_GameControllerAddMappingsFromRW +#undef SDL_GameControllerAddMappingsFromRW +#endif + +#ifdef SDL_GL_ResetAttributes +#undef SDL_GL_ResetAttributes +#endif + +#ifdef SDL_HasAVX +#undef SDL_HasAVX +#endif + +#ifdef SDL_GetDefaultAssertionHandler +#undef SDL_GetDefaultAssertionHandler +#endif + +#ifdef SDL_GetAssertionHandler +#undef SDL_GetAssertionHandler +#endif + +#ifdef SDL_DXGIGetOutputInfo +#undef SDL_DXGIGetOutputInfo +#endif + +#ifdef SDL_RenderIsClipEnabled +#undef SDL_RenderIsClipEnabled +#endif + +#ifdef SDL_WinRTRunApp +#undef SDL_WinRTRunApp +#endif + +#ifdef SDL_WarpMouseGlobal +#undef SDL_WarpMouseGlobal +#endif + +#ifdef SDL_WinRTGetFSPathUNICODE +#undef SDL_WinRTGetFSPathUNICODE +#endif + +#ifdef SDL_WinRTGetFSPathUTF8 +#undef SDL_WinRTGetFSPathUTF8 +#endif + +#ifdef SDL_sqrtf +#undef SDL_sqrtf +#endif + +#ifdef SDL_tan +#undef SDL_tan +#endif + +#ifdef SDL_tanf +#undef SDL_tanf +#endif + +#ifdef SDL_CaptureMouse +#undef SDL_CaptureMouse +#endif + +#ifdef SDL_SetWindowHitTest +#undef SDL_SetWindowHitTest +#endif + +#ifdef SDL_GetGlobalMouseState +#undef SDL_GetGlobalMouseState +#endif + +#ifdef SDL_HasAVX2 +#undef SDL_HasAVX2 +#endif + +#ifdef SDL_QueueAudio +#undef SDL_QueueAudio +#endif + +#ifdef SDL_GetQueuedAudioSize +#undef SDL_GetQueuedAudioSize +#endif + +#ifdef SDL_ClearQueuedAudio +#undef SDL_ClearQueuedAudio +#endif + +#ifdef SDL_GetGrabbedWindow +#undef SDL_GetGrabbedWindow +#endif + +#ifdef SDL_SetWindowsMessageHook +#undef SDL_SetWindowsMessageHook +#endif + +#ifdef SDL_JoystickCurrentPowerLevel +#undef SDL_JoystickCurrentPowerLevel +#endif + +#ifdef SDL_GameControllerFromInstanceID +#undef SDL_GameControllerFromInstanceID +#endif + +#ifdef SDL_JoystickFromInstanceID +#undef SDL_JoystickFromInstanceID +#endif + +#ifdef SDL_GetDisplayUsableBounds +#undef SDL_GetDisplayUsableBounds +#endif + +#ifdef SDL_GetWindowBordersSize +#undef SDL_GetWindowBordersSize +#endif + +#ifdef SDL_SetWindowOpacity +#undef SDL_SetWindowOpacity +#endif + +#ifdef SDL_GetWindowOpacity +#undef SDL_GetWindowOpacity +#endif + +#ifdef SDL_SetWindowInputFocus +#undef SDL_SetWindowInputFocus +#endif + +#ifdef SDL_SetWindowModalFor +#undef SDL_SetWindowModalFor +#endif + +#ifdef SDL_RenderSetIntegerScale +#undef SDL_RenderSetIntegerScale +#endif + +#ifdef SDL_RenderGetIntegerScale +#undef SDL_RenderGetIntegerScale +#endif + +#ifdef SDL_DequeueAudio +#undef SDL_DequeueAudio +#endif + +#ifdef SDL_SetWindowResizable +#undef SDL_SetWindowResizable +#endif + +#ifdef SDL_CreateRGBSurfaceWithFormat +#undef SDL_CreateRGBSurfaceWithFormat +#endif + +#ifdef SDL_CreateRGBSurfaceWithFormatFrom +#undef SDL_CreateRGBSurfaceWithFormatFrom +#endif + +#ifdef SDL_GetHintBoolean +#undef SDL_GetHintBoolean +#endif + +#ifdef SDL_JoystickGetDeviceVendor +#undef SDL_JoystickGetDeviceVendor +#endif + +#ifdef SDL_JoystickGetDeviceProduct +#undef SDL_JoystickGetDeviceProduct +#endif + +#ifdef SDL_JoystickGetDeviceProductVersion +#undef SDL_JoystickGetDeviceProductVersion +#endif + +#ifdef SDL_JoystickGetVendor +#undef SDL_JoystickGetVendor +#endif + +#ifdef SDL_JoystickGetProduct +#undef SDL_JoystickGetProduct +#endif + +#ifdef SDL_JoystickGetProductVersion +#undef SDL_JoystickGetProductVersion +#endif + +#ifdef SDL_GameControllerGetVendor +#undef SDL_GameControllerGetVendor +#endif + +#ifdef SDL_GameControllerGetProduct +#undef SDL_GameControllerGetProduct +#endif + +#ifdef SDL_GameControllerGetProductVersion +#undef SDL_GameControllerGetProductVersion +#endif + +#ifdef SDL_HasNEON +#undef SDL_HasNEON +#endif + +#ifdef SDL_GameControllerNumMappings +#undef SDL_GameControllerNumMappings +#endif + +#ifdef SDL_GameControllerMappingForIndex +#undef SDL_GameControllerMappingForIndex +#endif + +#ifdef SDL_JoystickGetAxisInitialState +#undef SDL_JoystickGetAxisInitialState +#endif + +#ifdef SDL_JoystickGetDeviceType +#undef SDL_JoystickGetDeviceType +#endif + +#ifdef SDL_JoystickGetType +#undef SDL_JoystickGetType +#endif + +#ifdef SDL_MemoryBarrierReleaseFunction +#undef SDL_MemoryBarrierReleaseFunction +#endif + +#ifdef SDL_MemoryBarrierAcquireFunction +#undef SDL_MemoryBarrierAcquireFunction +#endif + +#ifdef SDL_JoystickGetDeviceInstanceID +#undef SDL_JoystickGetDeviceInstanceID +#endif + +#ifdef SDL_utf8strlen +#undef SDL_utf8strlen +#endif + +#ifdef SDL_LoadFile_RW +#undef SDL_LoadFile_RW +#endif + +#ifdef SDL_wcscmp +#undef SDL_wcscmp +#endif + +#ifdef SDL_ComposeCustomBlendMode +#undef SDL_ComposeCustomBlendMode +#endif + +#ifdef SDL_DuplicateSurface +#undef SDL_DuplicateSurface +#endif + +#ifdef SDL_Vulkan_LoadLibrary +#undef SDL_Vulkan_LoadLibrary +#endif + +#ifdef SDL_Vulkan_GetVkGetInstanceProcAddr +#undef SDL_Vulkan_GetVkGetInstanceProcAddr +#endif + +#ifdef SDL_Vulkan_UnloadLibrary +#undef SDL_Vulkan_UnloadLibrary +#endif + +#ifdef SDL_Vulkan_GetInstanceExtensions +#undef SDL_Vulkan_GetInstanceExtensions +#endif + +#ifdef SDL_Vulkan_CreateSurface +#undef SDL_Vulkan_CreateSurface +#endif + +#ifdef SDL_Vulkan_GetDrawableSize +#undef SDL_Vulkan_GetDrawableSize +#endif + +#ifdef SDL_LockJoysticks +#undef SDL_LockJoysticks +#endif + +#ifdef SDL_UnlockJoysticks +#undef SDL_UnlockJoysticks +#endif + +#ifdef SDL_GetMemoryFunctions +#undef SDL_GetMemoryFunctions +#endif + +#ifdef SDL_SetMemoryFunctions +#undef SDL_SetMemoryFunctions +#endif + +#ifdef SDL_GetNumAllocations +#undef SDL_GetNumAllocations +#endif + +#ifdef SDL_NewAudioStream +#undef SDL_NewAudioStream +#endif + +#ifdef SDL_AudioStreamPut +#undef SDL_AudioStreamPut +#endif + +#ifdef SDL_AudioStreamGet +#undef SDL_AudioStreamGet +#endif + +#ifdef SDL_AudioStreamClear +#undef SDL_AudioStreamClear +#endif + +#ifdef SDL_AudioStreamAvailable +#undef SDL_AudioStreamAvailable +#endif + +#ifdef SDL_FreeAudioStream +#undef SDL_FreeAudioStream +#endif + +#ifdef SDL_AudioStreamFlush +#undef SDL_AudioStreamFlush +#endif + +#ifdef SDL_acosf +#undef SDL_acosf +#endif + +#ifdef SDL_asinf +#undef SDL_asinf +#endif + +#ifdef SDL_atanf +#undef SDL_atanf +#endif + +#ifdef SDL_atan2f +#undef SDL_atan2f +#endif + +#ifdef SDL_ceilf +#undef SDL_ceilf +#endif + +#ifdef SDL_copysignf +#undef SDL_copysignf +#endif + +#ifdef SDL_fabsf +#undef SDL_fabsf +#endif + +#ifdef SDL_floorf +#undef SDL_floorf +#endif + +#ifdef SDL_logf +#undef SDL_logf +#endif + +#ifdef SDL_powf +#undef SDL_powf +#endif + +#ifdef SDL_scalbnf +#undef SDL_scalbnf +#endif + +#ifdef SDL_fmod +#undef SDL_fmod +#endif + +#ifdef SDL_fmodf +#undef SDL_fmodf +#endif + +#ifdef SDL_SetYUVConversionMode +#undef SDL_SetYUVConversionMode +#endif + +#ifdef SDL_GetYUVConversionMode +#undef SDL_GetYUVConversionMode +#endif + +#ifdef SDL_GetYUVConversionModeForResolution +#undef SDL_GetYUVConversionModeForResolution +#endif + +#ifdef SDL_RenderGetMetalLayer +#undef SDL_RenderGetMetalLayer +#endif + +#ifdef SDL_RenderGetMetalCommandEncoder +#undef SDL_RenderGetMetalCommandEncoder +#endif + +#ifdef SDL_IsAndroidTV +#undef SDL_IsAndroidTV +#endif + +#ifdef SDL_WinRTGetDeviceFamily +#undef SDL_WinRTGetDeviceFamily +#endif + +#ifdef SDL_log10 +#undef SDL_log10 +#endif + +#ifdef SDL_log10f +#undef SDL_log10f +#endif + +#ifdef SDL_GameControllerMappingForDeviceIndex +#undef SDL_GameControllerMappingForDeviceIndex +#endif + +#ifdef SDL_LinuxSetThreadPriority +#undef SDL_LinuxSetThreadPriority +#endif + +#ifdef SDL_HasAVX512F +#undef SDL_HasAVX512F +#endif + +#ifdef SDL_IsChromebook +#undef SDL_IsChromebook +#endif + +#ifdef SDL_IsDeXMode +#undef SDL_IsDeXMode +#endif + +#ifdef SDL_AndroidBackButton +#undef SDL_AndroidBackButton +#endif + +#ifdef SDL_exp +#undef SDL_exp +#endif + +#ifdef SDL_expf +#undef SDL_expf +#endif + +#ifdef SDL_wcsdup +#undef SDL_wcsdup +#endif + +#ifdef SDL_GameControllerRumble +#undef SDL_GameControllerRumble +#endif + +#ifdef SDL_JoystickRumble +#undef SDL_JoystickRumble +#endif + +#ifdef SDL_NumSensors +#undef SDL_NumSensors +#endif + +#ifdef SDL_SensorGetDeviceName +#undef SDL_SensorGetDeviceName +#endif + +#ifdef SDL_SensorGetDeviceType +#undef SDL_SensorGetDeviceType +#endif + +#ifdef SDL_SensorGetDeviceNonPortableType +#undef SDL_SensorGetDeviceNonPortableType +#endif + +#ifdef SDL_SensorGetDeviceInstanceID +#undef SDL_SensorGetDeviceInstanceID +#endif + +#ifdef SDL_SensorOpen +#undef SDL_SensorOpen +#endif + +#ifdef SDL_SensorFromInstanceID +#undef SDL_SensorFromInstanceID +#endif + +#ifdef SDL_SensorGetName +#undef SDL_SensorGetName +#endif + +#ifdef SDL_SensorGetType +#undef SDL_SensorGetType +#endif + +#ifdef SDL_SensorGetNonPortableType +#undef SDL_SensorGetNonPortableType +#endif + +#ifdef SDL_SensorGetInstanceID +#undef SDL_SensorGetInstanceID +#endif + +#ifdef SDL_SensorGetData +#undef SDL_SensorGetData +#endif + +#ifdef SDL_SensorClose +#undef SDL_SensorClose +#endif + +#ifdef SDL_SensorUpdate +#undef SDL_SensorUpdate +#endif + +#ifdef SDL_IsTablet +#undef SDL_IsTablet +#endif + +#ifdef SDL_GetDisplayOrientation +#undef SDL_GetDisplayOrientation +#endif + +#ifdef SDL_HasColorKey +#undef SDL_HasColorKey +#endif + +#ifdef SDL_CreateThreadWithStackSize +#undef SDL_CreateThreadWithStackSize +#endif + +#ifdef SDL_JoystickGetDevicePlayerIndex +#undef SDL_JoystickGetDevicePlayerIndex +#endif + +#ifdef SDL_JoystickGetPlayerIndex +#undef SDL_JoystickGetPlayerIndex +#endif + +#ifdef SDL_GameControllerGetPlayerIndex +#undef SDL_GameControllerGetPlayerIndex +#endif + +#ifdef SDL_RenderFlush +#undef SDL_RenderFlush +#endif + +#ifdef SDL_RenderDrawPointF +#undef SDL_RenderDrawPointF +#endif + +#ifdef SDL_RenderDrawPointsF +#undef SDL_RenderDrawPointsF +#endif + +#ifdef SDL_RenderDrawLineF +#undef SDL_RenderDrawLineF +#endif + +#ifdef SDL_RenderDrawLinesF +#undef SDL_RenderDrawLinesF +#endif + +#ifdef SDL_RenderDrawRectF +#undef SDL_RenderDrawRectF +#endif + +#ifdef SDL_RenderDrawRectsF +#undef SDL_RenderDrawRectsF +#endif + +#ifdef SDL_RenderFillRectF +#undef SDL_RenderFillRectF +#endif + +#ifdef SDL_RenderFillRectsF +#undef SDL_RenderFillRectsF +#endif + +#ifdef SDL_RenderCopyF +#undef SDL_RenderCopyF +#endif + +#ifdef SDL_RenderCopyExF +#undef SDL_RenderCopyExF +#endif + +#ifdef SDL_GetTouchDeviceType +#undef SDL_GetTouchDeviceType +#endif + +#ifdef SDL_UIKitRunApp +#undef SDL_UIKitRunApp +#endif + +#ifdef SDL_SIMDGetAlignment +#undef SDL_SIMDGetAlignment +#endif + +#ifdef SDL_SIMDAlloc +#undef SDL_SIMDAlloc +#endif + +#ifdef SDL_SIMDFree +#undef SDL_SIMDFree +#endif + +#ifdef SDL_RWsize +#undef SDL_RWsize +#endif + +#ifdef SDL_RWseek +#undef SDL_RWseek +#endif + +#ifdef SDL_RWtell +#undef SDL_RWtell +#endif + +#ifdef SDL_RWread +#undef SDL_RWread +#endif + +#ifdef SDL_RWwrite +#undef SDL_RWwrite +#endif + +#ifdef SDL_RWclose +#undef SDL_RWclose +#endif + +#ifdef SDL_LoadFile +#undef SDL_LoadFile +#endif + +#ifdef SDL_Metal_CreateView +#undef SDL_Metal_CreateView +#endif + +#ifdef SDL_Metal_DestroyView +#undef SDL_Metal_DestroyView +#endif + +#ifdef SDL_LockTextureToSurface +#undef SDL_LockTextureToSurface +#endif + +#ifdef SDL_HasARMSIMD +#undef SDL_HasARMSIMD +#endif + +#ifdef SDL_strtokr +#undef SDL_strtokr +#endif + +#ifdef SDL_wcsstr +#undef SDL_wcsstr +#endif + +#ifdef SDL_wcsncmp +#undef SDL_wcsncmp +#endif + +#ifdef SDL_GameControllerTypeForIndex +#undef SDL_GameControllerTypeForIndex +#endif + +#ifdef SDL_GameControllerGetType +#undef SDL_GameControllerGetType +#endif + +#ifdef SDL_GameControllerFromPlayerIndex +#undef SDL_GameControllerFromPlayerIndex +#endif + +#ifdef SDL_GameControllerSetPlayerIndex +#undef SDL_GameControllerSetPlayerIndex +#endif + +#ifdef SDL_JoystickFromPlayerIndex +#undef SDL_JoystickFromPlayerIndex +#endif + +#ifdef SDL_JoystickSetPlayerIndex +#undef SDL_JoystickSetPlayerIndex +#endif + +#ifdef SDL_SetTextureScaleMode +#undef SDL_SetTextureScaleMode +#endif + +#ifdef SDL_GetTextureScaleMode +#undef SDL_GetTextureScaleMode +#endif + +#ifdef SDL_OnApplicationWillTerminate +#undef SDL_OnApplicationWillTerminate +#endif + +#ifdef SDL_OnApplicationDidReceiveMemoryWarning +#undef SDL_OnApplicationDidReceiveMemoryWarning +#endif + +#ifdef SDL_OnApplicationWillResignActive +#undef SDL_OnApplicationWillResignActive +#endif + +#ifdef SDL_OnApplicationDidEnterBackground +#undef SDL_OnApplicationDidEnterBackground +#endif + +#ifdef SDL_OnApplicationWillEnterForeground +#undef SDL_OnApplicationWillEnterForeground +#endif + +#ifdef SDL_OnApplicationDidBecomeActive +#undef SDL_OnApplicationDidBecomeActive +#endif + +#ifdef SDL_OnApplicationDidChangeStatusBarOrientation +#undef SDL_OnApplicationDidChangeStatusBarOrientation +#endif + +#ifdef SDL_GetAndroidSDKVersion +#undef SDL_GetAndroidSDKVersion +#endif + +#ifdef SDL_isupper +#undef SDL_isupper +#endif + +#ifdef SDL_islower +#undef SDL_islower +#endif + +#ifdef SDL_JoystickAttachVirtual +#undef SDL_JoystickAttachVirtual +#endif + +#ifdef SDL_JoystickDetachVirtual +#undef SDL_JoystickDetachVirtual +#endif + +#ifdef SDL_JoystickIsVirtual +#undef SDL_JoystickIsVirtual +#endif + +#ifdef SDL_JoystickSetVirtualAxis +#undef SDL_JoystickSetVirtualAxis +#endif + +#ifdef SDL_JoystickSetVirtualButton +#undef SDL_JoystickSetVirtualButton +#endif + +#ifdef SDL_JoystickSetVirtualHat +#undef SDL_JoystickSetVirtualHat +#endif + +#ifdef SDL_GetErrorMsg +#undef SDL_GetErrorMsg +#endif + +#ifdef SDL_LockSensors +#undef SDL_LockSensors +#endif + +#ifdef SDL_UnlockSensors +#undef SDL_UnlockSensors +#endif + +#ifdef SDL_Metal_GetLayer +#undef SDL_Metal_GetLayer +#endif + +#ifdef SDL_Metal_GetDrawableSize +#undef SDL_Metal_GetDrawableSize +#endif + +#ifdef SDL_trunc +#undef SDL_trunc +#endif + +#ifdef SDL_truncf +#undef SDL_truncf +#endif + +#ifdef SDL_GetPreferredLocales +#undef SDL_GetPreferredLocales +#endif + +#ifdef SDL_SIMDRealloc +#undef SDL_SIMDRealloc +#endif + +#ifdef SDL_AndroidRequestPermission +#undef SDL_AndroidRequestPermission +#endif + +#ifdef SDL_OpenURL +#undef SDL_OpenURL +#endif + +#ifdef SDL_HasSurfaceRLE +#undef SDL_HasSurfaceRLE +#endif + +#ifdef SDL_GameControllerHasLED +#undef SDL_GameControllerHasLED +#endif + +#ifdef SDL_GameControllerSetLED +#undef SDL_GameControllerSetLED +#endif + +#ifdef SDL_JoystickHasLED +#undef SDL_JoystickHasLED #endif -#ifdef SDL_strcmp -#undef SDL_strcmp +#ifdef SDL_JoystickSetLED +#undef SDL_JoystickSetLED #endif -#ifdef SDL_strncmp -#undef SDL_strncmp +#ifdef SDL_GameControllerRumbleTriggers +#undef SDL_GameControllerRumbleTriggers #endif -#ifdef SDL_strcasecmp -#undef SDL_strcasecmp +#ifdef SDL_JoystickRumbleTriggers +#undef SDL_JoystickRumbleTriggers #endif -#ifdef SDL_strncasecmp -#undef SDL_strncasecmp +#ifdef SDL_GameControllerHasAxis +#undef SDL_GameControllerHasAxis #endif -#ifdef SDL_sscanf -#undef SDL_sscanf +#ifdef SDL_GameControllerHasButton +#undef SDL_GameControllerHasButton #endif -#ifdef SDL_snprintf -#undef SDL_snprintf +#ifdef SDL_GameControllerGetNumTouchpads +#undef SDL_GameControllerGetNumTouchpads #endif -#ifdef SDL_vsnprintf -#undef SDL_vsnprintf +#ifdef SDL_GameControllerGetNumTouchpadFingers +#undef SDL_GameControllerGetNumTouchpadFingers #endif -#ifdef SDL_iconv_open -#undef SDL_iconv_open +#ifdef SDL_GameControllerGetTouchpadFinger +#undef SDL_GameControllerGetTouchpadFinger #endif -#ifdef SDL_iconv_close -#undef SDL_iconv_close +#ifdef SDL_crc32 +#undef SDL_crc32 #endif -#ifdef SDL_iconv -#undef SDL_iconv +#ifdef SDL_GameControllerGetSerial +#undef SDL_GameControllerGetSerial #endif -#ifdef SDL_iconv_string -#undef SDL_iconv_string +#ifdef SDL_JoystickGetSerial +#undef SDL_JoystickGetSerial #endif -#ifdef SDL_atoi -#undef SDL_atoi +#ifdef SDL_GameControllerHasSensor +#undef SDL_GameControllerHasSensor #endif -#ifdef SDL_setenv -#undef SDL_setenv +#ifdef SDL_GameControllerSetSensorEnabled +#undef SDL_GameControllerSetSensorEnabled +#endif + +#ifdef SDL_GameControllerIsSensorEnabled +#undef SDL_GameControllerIsSensorEnabled +#endif + +#ifdef SDL_GameControllerGetSensorData +#undef SDL_GameControllerGetSensorData +#endif + +#ifdef SDL_wcscasecmp +#undef SDL_wcscasecmp +#endif + +#ifdef SDL_wcsncasecmp +#undef SDL_wcsncasecmp +#endif + +#ifdef SDL_round +#undef SDL_round +#endif + +#ifdef SDL_roundf +#undef SDL_roundf +#endif + +#ifdef SDL_lround +#undef SDL_lround +#endif + +#ifdef SDL_lroundf +#undef SDL_lroundf +#endif + +#ifdef SDL_SoftStretchLinear +#undef SDL_SoftStretchLinear +#endif + +#ifdef SDL_RenderGetD3D11Device +#undef SDL_RenderGetD3D11Device +#endif + +#ifdef SDL_UpdateNVTexture +#undef SDL_UpdateNVTexture +#endif + +#ifdef SDL_SetWindowKeyboardGrab +#undef SDL_SetWindowKeyboardGrab +#endif + +#ifdef SDL_SetWindowMouseGrab +#undef SDL_SetWindowMouseGrab +#endif + +#ifdef SDL_GetWindowKeyboardGrab +#undef SDL_GetWindowKeyboardGrab +#endif + +#ifdef SDL_GetWindowMouseGrab +#undef SDL_GetWindowMouseGrab +#endif + +#ifdef SDL_isalpha +#undef SDL_isalpha +#endif + +#ifdef SDL_isalnum +#undef SDL_isalnum +#endif + +#ifdef SDL_isblank +#undef SDL_isblank +#endif + +#ifdef SDL_iscntrl +#undef SDL_iscntrl +#endif + +#ifdef SDL_isxdigit +#undef SDL_isxdigit +#endif + +#ifdef SDL_ispunct +#undef SDL_ispunct +#endif + +#ifdef SDL_isprint +#undef SDL_isprint +#endif + +#ifdef SDL_isgraph +#undef SDL_isgraph +#endif + +#ifdef SDL_AndroidShowToast +#undef SDL_AndroidShowToast +#endif + +#ifdef SDL_GetAudioDeviceSpec +#undef SDL_GetAudioDeviceSpec +#endif + +#ifdef SDL_TLSCleanup +#undef SDL_TLSCleanup +#endif + +#ifdef SDL_SetWindowAlwaysOnTop +#undef SDL_SetWindowAlwaysOnTop +#endif + +#ifdef SDL_FlashWindow +#undef SDL_FlashWindow +#endif + +#ifdef SDL_GameControllerSendEffect +#undef SDL_GameControllerSendEffect +#endif + +#ifdef SDL_JoystickSendEffect +#undef SDL_JoystickSendEffect +#endif + +#ifdef SDL_GameControllerGetSensorDataRate +#undef SDL_GameControllerGetSensorDataRate +#endif + +#ifdef SDL_SetTextureUserData +#undef SDL_SetTextureUserData +#endif + +#ifdef SDL_GetTextureUserData +#undef SDL_GetTextureUserData +#endif + +#ifdef SDL_RenderGeometry +#undef SDL_RenderGeometry +#endif + +#ifdef SDL_RenderGeometryRaw +#undef SDL_RenderGeometryRaw +#endif + +#ifdef SDL_RenderSetVSync +#undef SDL_RenderSetVSync +#endif + +#ifdef SDL_asprintf +#undef SDL_asprintf +#endif + +#ifdef SDL_vasprintf +#undef SDL_vasprintf +#endif + +#ifdef SDL_GetWindowICCProfile +#undef SDL_GetWindowICCProfile +#endif + +#ifdef SDL_GetTicks64 +#undef SDL_GetTicks64 +#endif + +#ifdef SDL_LinuxSetThreadPriorityAndPolicy +#undef SDL_LinuxSetThreadPriorityAndPolicy +#endif + +#ifdef SDL_GameControllerGetAppleSFSymbolsNameForButton +#undef SDL_GameControllerGetAppleSFSymbolsNameForButton +#endif + +#ifdef SDL_GameControllerGetAppleSFSymbolsNameForAxis +#undef SDL_GameControllerGetAppleSFSymbolsNameForAxis +#endif + +#ifdef SDL_hid_init +#undef SDL_hid_init +#endif + +#ifdef SDL_hid_exit +#undef SDL_hid_exit +#endif + +#ifdef SDL_hid_device_change_count +#undef SDL_hid_device_change_count +#endif + +#ifdef SDL_hid_enumerate +#undef SDL_hid_enumerate +#endif + +#ifdef SDL_hid_free_enumeration +#undef SDL_hid_free_enumeration +#endif + +#ifdef SDL_hid_open +#undef SDL_hid_open +#endif + +#ifdef SDL_hid_open_path +#undef SDL_hid_open_path +#endif + +#ifdef SDL_hid_write +#undef SDL_hid_write +#endif + +#ifdef SDL_hid_read_timeout +#undef SDL_hid_read_timeout +#endif + +#ifdef SDL_hid_read +#undef SDL_hid_read +#endif + +#ifdef SDL_hid_set_nonblocking +#undef SDL_hid_set_nonblocking +#endif + +#ifdef SDL_hid_send_feature_report +#undef SDL_hid_send_feature_report +#endif + +#ifdef SDL_hid_get_feature_report +#undef SDL_hid_get_feature_report +#endif + +#ifdef SDL_hid_close +#undef SDL_hid_close +#endif + +#ifdef SDL_hid_get_manufacturer_string +#undef SDL_hid_get_manufacturer_string +#endif + +#ifdef SDL_hid_get_product_string +#undef SDL_hid_get_product_string +#endif + +#ifdef SDL_hid_get_serial_number_string +#undef SDL_hid_get_serial_number_string +#endif + +#ifdef SDL_hid_get_indexed_string +#undef SDL_hid_get_indexed_string +#endif + +#ifdef SDL_SetWindowMouseRect +#undef SDL_SetWindowMouseRect +#endif + +#ifdef SDL_GetWindowMouseRect +#undef SDL_GetWindowMouseRect +#endif + +#ifdef SDL_RenderWindowToLogical +#undef SDL_RenderWindowToLogical +#endif + +#ifdef SDL_RenderLogicalToWindow +#undef SDL_RenderLogicalToWindow +#endif + +#ifdef SDL_JoystickHasRumble +#undef SDL_JoystickHasRumble +#endif + +#ifdef SDL_JoystickHasRumbleTriggers +#undef SDL_JoystickHasRumbleTriggers +#endif + +#ifdef SDL_GameControllerHasRumble +#undef SDL_GameControllerHasRumble +#endif + +#ifdef SDL_GameControllerHasRumbleTriggers +#undef SDL_GameControllerHasRumbleTriggers +#endif + +#ifdef SDL_hid_ble_scan +#undef SDL_hid_ble_scan +#endif + +#ifdef SDL_PremultiplyAlpha +#undef SDL_PremultiplyAlpha +#endif + +#ifdef SDL_AndroidSendMessage +#undef SDL_AndroidSendMessage +#endif + +#ifdef SDL_GetTouchName +#undef SDL_GetTouchName +#endif + +#ifdef SDL_ClearComposition +#undef SDL_ClearComposition +#endif + +#ifdef SDL_IsTextInputShown +#undef SDL_IsTextInputShown +#endif + +#ifdef SDL_HasIntersectionF +#undef SDL_HasIntersectionF +#endif + +#ifdef SDL_IntersectFRect +#undef SDL_IntersectFRect +#endif + +#ifdef SDL_UnionFRect +#undef SDL_UnionFRect +#endif + +#ifdef SDL_EncloseFPoints +#undef SDL_EncloseFPoints +#endif + +#ifdef SDL_IntersectFRectAndLine +#undef SDL_IntersectFRectAndLine +#endif + +#ifdef SDL_RenderGetWindow +#undef SDL_RenderGetWindow +#endif + +#ifdef SDL_bsearch +#undef SDL_bsearch +#endif + +#ifdef SDL_GameControllerPathForIndex +#undef SDL_GameControllerPathForIndex +#endif + +#ifdef SDL_GameControllerPath +#undef SDL_GameControllerPath +#endif + +#ifdef SDL_JoystickPathForIndex +#undef SDL_JoystickPathForIndex +#endif + +#ifdef SDL_JoystickPath +#undef SDL_JoystickPath +#endif + +#ifdef SDL_JoystickAttachVirtualEx +#undef SDL_JoystickAttachVirtualEx +#endif + +#ifdef SDL_GameControllerGetFirmwareVersion +#undef SDL_GameControllerGetFirmwareVersion +#endif + +#ifdef SDL_JoystickGetFirmwareVersion +#undef SDL_JoystickGetFirmwareVersion +#endif + +#ifdef SDL_GUIDToString +#undef SDL_GUIDToString +#endif + +#ifdef SDL_GUIDFromString +#undef SDL_GUIDFromString +#endif + +#ifdef SDL_HasLSX +#undef SDL_HasLSX +#endif + +#ifdef SDL_HasLASX +#undef SDL_HasLASX +#endif + +#ifdef SDL_RenderGetD3D12Device +#undef SDL_RenderGetD3D12Device +#endif + +#ifdef SDL_utf8strnlen +#undef SDL_utf8strnlen +#endif + +#ifdef SDL_GDKGetTaskQueue +#undef SDL_GDKGetTaskQueue +#endif + +#ifdef SDL_GDKRunApp +#undef SDL_GDKRunApp +#endif + +#ifdef SDL_GetOriginalMemoryFunctions +#undef SDL_GetOriginalMemoryFunctions +#endif + +#ifdef SDL_ResetKeyboard +#undef SDL_ResetKeyboard +#endif + +#ifdef SDL_GetDefaultAudioInfo +#undef SDL_GetDefaultAudioInfo +#endif + +#ifdef SDL_GetPointDisplayIndex +#undef SDL_GetPointDisplayIndex +#endif + +#ifdef SDL_GetRectDisplayIndex +#undef SDL_GetRectDisplayIndex +#endif + +#ifdef SDL_ResetHint +#undef SDL_ResetHint +#endif + +#ifdef SDL_crc16 +#undef SDL_crc16 +#endif + +#ifdef SDL_GetWindowSizeInPixels +#undef SDL_GetWindowSizeInPixels +#endif + +#ifdef SDL_GetJoystickGUIDInfo +#undef SDL_GetJoystickGUIDInfo +#endif + +#ifdef SDL_SetPrimarySelectionText +#undef SDL_SetPrimarySelectionText +#endif + +#ifdef SDL_GetPrimarySelectionText +#undef SDL_GetPrimarySelectionText +#endif + +#ifdef SDL_HasPrimarySelectionText +#undef SDL_HasPrimarySelectionText +#endif + +#ifdef SDL_GameControllerGetSensorDataWithTimestamp +#undef SDL_GameControllerGetSensorDataWithTimestamp +#endif + +#ifdef SDL_SensorGetDataWithTimestamp +#undef SDL_SensorGetDataWithTimestamp +#endif + +#ifdef SDL_ResetHints +#undef SDL_ResetHints +#endif + +#ifdef SDL_strcasestr +#undef SDL_strcasestr +#endif + +#ifdef SDL_GDKSuspendComplete +#undef SDL_GDKSuspendComplete #endif #endif From 3b8244745668a0af71d1b19694e524ca8e7489ef Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sat, 4 Feb 2023 20:55:40 +0300 Subject: [PATCH 440/606] replace all SDL_zero() with SDL20_zero() --- src/SDL12_compat.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 5b3a5db0a..379655016 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -123,6 +123,7 @@ extern "C" { #define SDL20_InvalidParamError(param) SDL20_SetError("Parameter '%s' is invalid", (param)) #define SDL20_zero(x) SDL20_memset(&(x), 0, sizeof((x))) #define SDL20_zerop(x) SDL20_memset((x), 0, sizeof(*(x))) +#define SDL20_zeroa(x) SDL20_memset((x), 0, sizeof((x))) #define SDL_ReportAssertion SDL20_ReportAssertion /* From SDL2.0's SDL_bits.h: a force-inlined function. */ @@ -5454,7 +5455,7 @@ EndVidModeCreate(void) VideoConvertSurface20 = NULL; } - SDL_zero(OpenGLFuncs); + SDL20_zero(OpenGLFuncs); OpenGLBlitLockCount = 0; OpenGLLogicalScalingWidth = 0; OpenGLLogicalScalingHeight = 0; @@ -5515,7 +5516,7 @@ LoadOpenGLFunctions(void) int major = 0, minor = 0; /* load core functions so we can guess about a few other things. */ - SDL_zero(OpenGLFuncs); + SDL20_zero(OpenGLFuncs); OpenGLFuncs.SUPPORTS_Core = SDL_TRUE; #define OPENGL_SYM(ext,rc,fn,params,args,ret) OpenGLFuncs.fn = \ (OpenGLFuncs.SUPPORTS_##ext)? (openglfn_##fn##_t)SDL20_GL_GetProcAddress(#fn) : NULL; @@ -5967,7 +5968,7 @@ SetVideoModeImpl(int width, int height, int bpp, Uint32 flags12) SDL20_GL_MakeCurrent(NULL, NULL); SDL20_GL_DeleteContext(VideoGLContext20); VideoGLContext20 = NULL; - SDL_zero(OpenGLFuncs); + SDL20_zero(OpenGLFuncs); OpenGLBlitTexture = 0; OpenGLBlitLockCount = 0; OpenGLLogicalScalingWidth = 0; @@ -7337,7 +7338,7 @@ SDL_GetWMInfo(SDL12_SysWMinfo *info12) temp_window = SDL_TRUE; } - SDL_zero(info20); + SDL20_zero(info20); /* SDL2, before the version scheme change, would fail if the requested version wasn't 2.0.x, so if the SDL2 is from before this was fixed, we need to lie about the @@ -8726,7 +8727,7 @@ SDL_CDOpen(int drive) if (retval->numtracks > 0) { SDL_AudioSpec want; - SDL_zero(want); + SDL20_zero(want); want.freq = 44100; want.format = AUDIO_F32SYS; want.channels = 2; @@ -9465,7 +9466,7 @@ SDL_CloseAudio(void) static SDL_AudioCVT * AudioCVT12to20(const SDL12_AudioCVT *cvt12, SDL_AudioCVT *cvt20) { - SDL_zerop(cvt20); + SDL20_zerop(cvt20); cvt20->needed = cvt12->needed; cvt20->src_format = cvt12->src_format; cvt20->dst_format = cvt12->dst_format; @@ -9483,7 +9484,7 @@ AudioCVT12to20(const SDL12_AudioCVT *cvt12, SDL_AudioCVT *cvt20) static SDL12_AudioCVT * AudioCVT20to12(const SDL_AudioCVT *cvt20, SDL12_AudioCVT *cvt12) { - SDL_zerop(cvt12); + SDL20_zerop(cvt12); cvt12->needed = cvt20->needed; cvt12->src_format = cvt20->src_format; cvt12->dst_format = cvt20->dst_format; @@ -9582,7 +9583,7 @@ SDL_BuildAudioCVT(SDL12_AudioCVT *cvt12, Uint16 src_format, Uint8 src_channels, { int retval = 0; - SDL_zerop(cvt12); /* SDL 1.2 derefences cvt12 without checking for NULL */ + SDL20_zerop(cvt12); /* SDL 1.2 derefences cvt12 without checking for NULL */ if (!WantCompatibilityAudioCVT) { SDL_AudioCVT cvt20; From 5537203a7f9246d5acd490b92df0477ea042d6a1 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sat, 4 Feb 2023 20:55:40 +0300 Subject: [PATCH 441/606] minor style tidy-up. --- src/SDL12_compat.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 379655016..428d2ed10 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -8234,12 +8234,14 @@ SDL_RWFromConstMem(const void *mem, int size) return RWops20to12(SDL20_RWFromConstMem(mem, size)); } -#define READ_AND_BYTESWAP(endian, bits) \ - DECLSPEC12 Uint##bits SDLCALL SDL_Read##endian##bits(SDL12_RWops *rwops12) { \ - Uint##bits val; rwops12->read(rwops12, &val, sizeof (val), 1); \ - return SDL_Swap##endian##bits(val); \ - } - +#define READ_AND_BYTESWAP(endian, bits) \ +DECLSPEC12 Uint##bits SDLCALL \ +SDL_Read##endian##bits(SDL12_RWops *rwops12) \ +{ \ + Uint##bits val; \ + rwops12->read(rwops12, &val, sizeof (val), 1); \ + return SDL_Swap##endian##bits(val); \ +} READ_AND_BYTESWAP(LE,16) READ_AND_BYTESWAP(BE,16) READ_AND_BYTESWAP(LE,32) @@ -8248,11 +8250,13 @@ READ_AND_BYTESWAP(LE,64) READ_AND_BYTESWAP(BE,64) #undef READ_AND_BYTESWAP -#define BYTESWAP_AND_WRITE(endian, bits) \ - DECLSPEC12 int SDLCALL SDL_Write##endian##bits(SDL12_RWops *rwops12, Uint##bits val) { \ - val = SDL_Swap##endian##bits(val); \ - return rwops12->write(rwops12, &val, sizeof (val), 1); \ - } +#define BYTESWAP_AND_WRITE(endian, bits) \ +DECLSPEC12 int SDLCALL \ +SDL_Write##endian##bits(SDL12_RWops *rwops12, Uint##bits val) \ +{ \ + val = SDL_Swap##endian##bits(val); \ + return rwops12->write(rwops12, &val, sizeof (val), 1); \ +} BYTESWAP_AND_WRITE(LE,16) BYTESWAP_AND_WRITE(BE,16) BYTESWAP_AND_WRITE(LE,32) From 2eae59e0a2b5bce5c1334d51f440a59c38a2ee9a Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sat, 4 Feb 2023 20:55:40 +0300 Subject: [PATCH 442/606] restore buildability with c++ compilers. --- src/SDL12_compat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 428d2ed10..4a8bc01a4 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -8219,7 +8219,7 @@ SDL_RWFromFile(const char *file, const char *mode) DECLSPEC12 SDL12_RWops * SDLCALL SDL_RWFromFP(void *io, int autoclose) { - return RWops20to12(SDL20_RWFromFP(io, autoclose)); + return RWops20to12(SDL20_RWFromFP(io, autoclose ? SDL_TRUE : SDL_FALSE)); } DECLSPEC12 SDL12_RWops * SDLCALL From 0adf9aa009ce336d8358ad6d0865e6dc0647f171 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Thu, 9 Feb 2023 01:21:32 +0300 Subject: [PATCH 443/606] init: eliminate lstrcpyA() and wsprintfA() dependencies on windows. a stpcpy() and an itoa() implementation are enough to replace them. (backported from sdl2-compat) --- src/SDL12_compat.c | 62 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 51 insertions(+), 11 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 4a8bc01a4..4f3daa72a 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1053,6 +1053,41 @@ SDL20_atoi(const char *str) return SDL20_strtol(str, NULL, 10); } +static char * +SDL12COMPAT_stpcpy(char *dst, const char *src) +{ + while ((*dst++ = *src++) != '\0') { + /**/; + } + return --dst; +} + +static void +SDL12COMPAT_itoa(char *dst, int val) +{ + char *ptr, temp; + + if (val < 0) { + *dst++ = '-'; + val = -val; + } + ptr = dst; + + do { + *ptr++ = '0' + (val % 10); + val /= 10; + } while (val > 0); + *ptr-- = '\0'; + + /* correct the order of digits */ + do { + temp = *dst; + *dst++ = *ptr; + *ptr-- = temp; + } while (ptr > dst); +} + + /* Obviously we can't use SDL_LoadObject() to load SDL2. :) */ static char loaderror[256]; #if defined(_WIN32) @@ -1064,16 +1099,12 @@ static char loaderror[256]; #define LoadSDL20Library() ((Loaded_SDL20 = LoadLibraryA(SDL20_LIBNAME)) != NULL) #define LookupSDL20Sym(sym) (void *)GetProcAddress(Loaded_SDL20, sym) #define CloseSDL20Library() { if (Loaded_SDL20) { FreeLibrary(Loaded_SDL20); Loaded_SDL20 = NULL; } } - #define strcpy_fn lstrcpyA - #define sprintf_fn wsprintfA #elif defined(__OS2__) #include #define DIRSEP "\\" #define SDL20_LIBNAME "SDL2.dll" #define SDL20_LIBNAME2 "SDL2" /* if loading from LIBPATH */ #define SDL20_REQUIRED_VER SDL_VERSIONNUM(2,0,7) - #define strcpy_fn strcpy - #define sprintf_fn sprintf static HMODULE Loaded_SDL20 = NULLHANDLE; static SDL_bool LoadSDL20Library(void) { char err[256]; @@ -1104,8 +1135,6 @@ static char loaderror[256]; #define SDL20_LIBNAME2 "libSDL2-2.0.dylib" #define SDL20_FRAMEWORK "SDL2.framework/Versions/A/SDL2" #define SDL20_REQUIRED_VER SDL_VERSIONNUM(2,0,7) - #define strcpy_fn strcpy - #define sprintf_fn sprintf static void *Loaded_SDL20 = NULL; #define LookupSDL20Sym(sym) dlsym(Loaded_SDL20, sym) #define CloseSDL20Library() { if (Loaded_SDL20) { dlclose(Loaded_SDL20); Loaded_SDL20 = NULL; } } @@ -1162,8 +1191,6 @@ static char loaderror[256]; #define LoadSDL20Library() ((Loaded_SDL20 = dlopen(SDL20_LIBNAME, RTLD_LOCAL|RTLD_NOW)) != NULL) #define LookupSDL20Sym(sym) dlsym(Loaded_SDL20, sym) #define CloseSDL20Library() { if (Loaded_SDL20) { dlclose(Loaded_SDL20); Loaded_SDL20 = NULL; } } - #define strcpy_fn strcpy - #define sprintf_fn sprintf #else #error Please define your platform. #endif @@ -1179,7 +1206,8 @@ LoadSDL20Symbol(const char *fn, int *okay) if (*okay) { /* only bother trying if we haven't previously failed. */ retval = LookupSDL20Sym(fn); if (retval == NULL) { - sprintf_fn(loaderror, "%s missing in SDL2 library.", fn); + char *p = SDL12COMPAT_stpcpy(loaderror, fn); + SDL12COMPAT_stpcpy(p, " missing in SDL2 library."); *okay = 0; } } @@ -1406,7 +1434,7 @@ LoadSDL20(void) okay = LoadSDL20Library(); if (!okay) { - strcpy_fn(loaderror, "Failed loading SDL2 library."); + SDL12COMPAT_stpcpy(loaderror, "Failed loading SDL2 library."); } else { #define SDL20_SYM(rc,fn,params,args,ret) SDL20_##fn = (SDL20_##fn##_t) LoadSDL20Symbol("SDL_" #fn, &okay); #include "SDL20_syms.h" @@ -1416,7 +1444,19 @@ LoadSDL20(void) LinkedSDL2VersionInt = SDL_VERSIONNUM(v.major, v.minor, v.patch); okay = (LinkedSDL2VersionInt >= SDL20_REQUIRED_VER); if (!okay) { - sprintf_fn(loaderror, "SDL2 %d.%d.%d library is too old.", v.major, v.minor, v.patch); + char value[12]; + char *p = SDL12COMPAT_stpcpy(loaderror, "SDL2 "); + + SDL12COMPAT_itoa(value, v.major); + p = SDL12COMPAT_stpcpy(p, value); + *p++ = '.'; + SDL12COMPAT_itoa(value, v.minor); + p = SDL12COMPAT_stpcpy(p, value); + *p++ = '.'; + SDL12COMPAT_itoa(value, v.patch); + p = SDL12COMPAT_stpcpy(p, value); + + SDL12COMPAT_stpcpy(p, " library is too old."); } else { WantDebugLogging = SDL12Compat_GetHintBoolean("SDL12COMPAT_DEBUG_LOGGING", SDL_FALSE); if (WantDebugLogging) { From 10fa8dd64d97af3ff9fa46e50197586f7383db1e Mon Sep 17 00:00:00 2001 From: Sylvain Date: Thu, 23 Mar 2023 10:48:37 +0100 Subject: [PATCH 444/606] Compiling with Clang on Windows fails at version.rc --- src/version.rc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.rc b/src/version.rc index b83fd2b18..158b04b4e 100644 --- a/src/version.rc +++ b/src/version.rc @@ -19,7 +19,7 @@ BEGIN VALUE "FileDescription", "SDL\0" VALUE "FileVersion", "1, 2, 61, 0\0" VALUE "InternalName", "SDL\0" - VALUE "LegalCopyright", "Copyright © 2022 Sam Lantinga\0" + VALUE "LegalCopyright", "Copyright (C) 2022 Sam Lantinga\0" VALUE "OriginalFilename", "SDL.dll\0" VALUE "ProductName", "Simple DirectMedia Layer 1.2 wrapper\0" VALUE "ProductVersion", "1, 2, 61, 0\0" From b48b470b15ff64c769a2463b08842b297067e575 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 28 Mar 2023 11:14:32 -0400 Subject: [PATCH 445/606] Updated copyright for 2023. --- LICENSE.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE.txt b/LICENSE.txt index a41260a29..b25acf74f 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,4 +1,4 @@ -Copyright (C) 1997-2022 Sam Lantinga +Copyright (C) 1997-2023 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages From 8d355d2c4d55f5d8b75f6bae78370f393142ca69 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sat, 1 Apr 2023 14:10:10 +0300 Subject: [PATCH 446/606] minor tidy-up. --- src/SDL12_compat.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 4f3daa72a..43f49c098 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1448,11 +1448,9 @@ LoadSDL20(void) char *p = SDL12COMPAT_stpcpy(loaderror, "SDL2 "); SDL12COMPAT_itoa(value, v.major); - p = SDL12COMPAT_stpcpy(p, value); - *p++ = '.'; + p = SDL12COMPAT_stpcpy(p, value); *p++ = '.'; SDL12COMPAT_itoa(value, v.minor); - p = SDL12COMPAT_stpcpy(p, value); - *p++ = '.'; + p = SDL12COMPAT_stpcpy(p, value); *p++ = '.'; SDL12COMPAT_itoa(value, v.patch); p = SDL12COMPAT_stpcpy(p, value); From 865e832d47381cbc224cce98c4a18d4a3783d055 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sat, 1 Apr 2023 14:10:10 +0300 Subject: [PATCH 447/606] updated cpuid code from SDL3 --- src/SDL12_compat.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 43f49c098..b7f9e9429 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1620,7 +1620,7 @@ SDL_revcpy(void *_dst, const void *_src, size_t len) /* SDL2 doesn't have MMXExt / 3dNowExt. */ -#if defined(__GNUC__) && defined(__i386__) +#if (defined(__GNUC__) || defined(__llvm__)) && defined(__i386__) #define cpuid(func, a, b, c, d) \ __asm__ __volatile__ ( \ " pushl %%ebx \n" \ @@ -1629,7 +1629,7 @@ SDL_revcpy(void *_dst, const void *_src, size_t len) " movl %%ebx, %%esi \n" \ " popl %%ebx \n" : \ "=a" (a), "=S" (b), "=c" (c), "=d" (d) : "a" (func)) -#elif defined(__GNUC__) && defined(__x86_64__) +#elif (defined(__GNUC__) || defined(__llvm__)) && defined(__x86_64__) #define cpuid(func, a, b, c, d) \ __asm__ __volatile__ ( \ " pushq %%rbx \n" \ @@ -1649,12 +1649,13 @@ SDL_revcpy(void *_dst, const void *_src, size_t len) __asm mov c, ecx \ __asm mov d, edx \ } -#elif defined(_MSC_VER) && defined(_M_X64) +#elif (defined(_MSC_VER) && defined(_M_X64)) +/* Use __cpuidex instead of __cpuid because ICL does not clear ecx register */ #include #define cpuid(func, a, b, c, d) \ { \ int CPUInfo[4]; \ - __cpuid(CPUInfo, func); \ + __cpuidex(CPUInfo, func, 0); \ a = CPUInfo[0]; \ b = CPUInfo[1]; \ c = CPUInfo[2]; \ From 016d5cbd1ec7044349b5ae26399473ae257cce89 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sat, 1 Apr 2023 20:37:40 +0300 Subject: [PATCH 448/606] SDL20_include_wrapper.h: undefine more macros from SDL2 headers. --- src/SDL20_include_wrapper.h | 91 +++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) diff --git a/src/SDL20_include_wrapper.h b/src/SDL20_include_wrapper.h index b461e10e7..55c04d6fe 100644 --- a/src/SDL20_include_wrapper.h +++ b/src/SDL20_include_wrapper.h @@ -4417,6 +4417,97 @@ typedef void (__cdecl *pfnSDL_CurrentEndThread) (unsigned); #undef SDL_GDKSuspendComplete #endif +/* undefine these macros too: */ +/* redefine using SDL2_xxx, if needed. */ + +#ifdef SDL_enabled_assert +#undef SDL_enabled_assert +#endif + +#ifdef SDL_OutOfMemory +#undef SDL_OutOfMemory +#endif + +#ifdef SDL_Unsupported +#undef SDL_Unsupported +#endif + +#ifdef SDL_InvalidParamError +#undef SDL_InvalidParamError +#endif + +#ifdef AtomicIncRef +#undef AtomicIncRef +#endif + +#ifdef SDL_AtomicDecRef +#undef SDL_AtomicDecRef +#endif + +#ifdef SDL_copyp +#undef SDL_copyp +#endif + +#ifdef SDL_zero +#undef SDL_zero +#endif + +#ifdef SDL_zeroa +#undef SDL_zeroa +#endif + +#ifdef SDL_zerop +#undef SDL_zerop +#endif + +#ifdef SDL_stack_alloc +#undef SDL_stack_alloc +#endif + +#ifdef SDL_stack_free +#undef SDL_stack_free +#endif + +#ifdef SDL_iconv_utf8_locale +#undef SDL_iconv_utf8_locale +#endif + +#ifdef SDL_iconv_utf8_ucs2 +#undef SDL_iconv_utf8_ucs2 +#endif + +#ifdef SDL_iconv_utf8_ucs4 +#undef SDL_iconv_utf8_ucs4 +#endif + +#ifdef SDL_iconv_wchar_utf8 +#undef SDL_iconv_wchar_utf8 +#endif + +#ifdef SDL_LoadWAV +#undef SDL_LoadWAV +#endif + +#ifdef SDL_LoadBMP +#undef SDL_LoadBMP +#endif + +#ifdef SDL_SaveBMP +#undef SDL_SaveBMP +#endif + +#ifdef SDL_GameControllerAddMappingsFromFile +#undef SDL_GameControllerAddMappingsFromFile +#endif + +#ifdef SDL_iOSSetAnimationCallback +#undef SDL_iOSSetAnimationCallback +#endif + +#ifdef SDL_iOSSetEventPump +#undef SDL_iOSSetEventPump +#endif + #endif /* vi: set ts=4 sw=4 expandtab: */ From 256ae3304425c205e82986ba22d2cc8284e855af Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sat, 1 Apr 2023 20:40:10 +0300 Subject: [PATCH 449/606] fix SDL_assert() after previous commit. --- src/SDL12_compat.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index b7f9e9429..42e9aec73 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -126,6 +126,21 @@ extern "C" { #define SDL20_zeroa(x) SDL20_memset((x), 0, sizeof((x))) #define SDL_ReportAssertion SDL20_ReportAssertion +/* for SDL_assert() : */ +#define SDL_enabled_assert(condition) \ +do { \ + while ( !(condition) ) { \ + static struct SDL_AssertData sdl_assert_data = { 0, 0, #condition, 0, 0, 0, 0 }; \ + const SDL_AssertState sdl_assert_state = SDL20_ReportAssertion(&sdl_assert_data, SDL_FUNCTION, SDL_FILE, SDL_LINE); \ + if (sdl_assert_state == SDL_ASSERTION_RETRY) { \ + continue; /* go again. */ \ + } else if (sdl_assert_state == SDL_ASSERTION_BREAK) { \ + SDL_TriggerBreakpoint(); \ + } \ + break; /* not retrying. */ \ + } \ +} while (SDL_NULL_WHILE_LOOP_CONDITION) + /* From SDL2.0's SDL_bits.h: a force-inlined function. */ #if defined(__WATCOMC__) && defined(__386__) extern __inline int _SDL20_bsr_watcom(Uint32); From 8662325b370b2a946061a758e22bd63bd77457a2 Mon Sep 17 00:00:00 2001 From: Henri Valta Date: Fri, 7 Apr 2023 12:32:47 +0300 Subject: [PATCH 450/606] Leave pixels pointer valid after SDL_UnlockYUVOverlay --- src/SDL12_compat.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 42e9aec73..edbe98a87 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -7660,9 +7660,10 @@ SDL_DisplayYUVOverlay(SDL12_Overlay *overlay12, SDL12_Rect *dstrect12) DECLSPEC12 void SDLCALL SDL_UnlockYUVOverlay(SDL12_Overlay *overlay12) { - if (overlay12) { + /* MLT SDL1 consumer uses locks, but accesses pixels pointer outside the lock, so don't null the pixels pointer. */ + /*if (overlay12) { overlay12->pixels = NULL; - } + }*/ } DECLSPEC12 void SDLCALL From bd3be23cf9f952ec13d5654cc1dc9c4e3801ff69 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sun, 14 May 2023 00:37:16 -0400 Subject: [PATCH 451/606] surface: 1.2 colorkeys were ignored if the surface had an alpha channel. Without this, the main menu on tuxfootball is wrong, since it's trying to draw white text from an RGBA surface with a white colorkey set. Since classic 1.2 would ignore the colorkey, this worked, but SDL2 still honors the colorkey to discard pixels before alpha-blending what's left. Fixes #265. --- src/SDL12_compat.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index edbe98a87..f29e98f47 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -6590,6 +6590,10 @@ SDL_SetColorKey(SDL12_Surface *surface12, Uint32 flag12, Uint32 key) if (addkey) { surface12->flags |= SDL12_SRCCOLORKEY; + /* you could set a color key on a 1.2 surface that had an alpha channel, but it would be ignored during blits. */ + if (surface12->format->Amask) { + SDL20_SetColorKey(surface12->surface20, SDL_FALSE, key); + } } else { surface12->flags &= ~SDL12_SRCCOLORKEY; } From 85031ff680c1d0be3968f45f58e7733873929e0c Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 15 May 2023 23:42:06 -0400 Subject: [PATCH 452/606] surface: Set SDL_SRCALPHA on newly-created surfaces the same way as 1.2. Reference Issue #244. --- src/SDL12_compat.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index f29e98f47..b8bdd2a2c 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -5134,7 +5134,7 @@ SDL_CreateRGBSurface(Uint32 flags12, int width, int height, int depth, Uint32 Rm SetPalette12ForMasks(surface12, Rmask, Gmask, Bmask); - if (flags12 & SDL12_SRCALPHA) { + if (Amask != 0) { surface12->flags |= SDL12_SRCALPHA; SDL20_SetSurfaceBlendMode(surface20, SDL_BLENDMODE_BLEND); } @@ -6619,7 +6619,7 @@ SDL_ConvertSurface(SDL12_Surface *src12, const SDL12_PixelFormat *format12, Uint if (!retval) { SDL20_FreeSurface(surface20); } else { - if (flags12 & SDL12_SRCALPHA) { + if (retval->format->Amask != 0) { SDL20_SetSurfaceBlendMode(surface20, SDL_BLENDMODE_BLEND); retval->flags |= SDL12_SRCALPHA; } From 82b9b50a40072c468f854b47dd3e44ff6e25ab87 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 16 May 2023 14:35:13 -0400 Subject: [PATCH 453/606] surface: Add a quirk to disable destination alpha preservation. This makes Freedroid render its bots correctly. Fixes #244. --- src/SDL12_compat.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index b8bdd2a2c..cea627a84 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1056,7 +1056,7 @@ static SDL_bool VideoSurfaceUpdatedInBackgroundThread = SDL_FALSE; static SDL_bool AllowThreadedDraws = SDL_FALSE; static SDL_bool AllowThreadedPumps = SDL_FALSE; static SDL_bool WantCompatibilityAudioCVT = SDL_FALSE; - +static SDL_bool PreserveDestinationAlpha = SDL_TRUE; /* This is a KEYDOWN event which is being held for a follow-up TEXTINPUT */ static SDL12_Event PendingKeydownEvent; @@ -1246,6 +1246,9 @@ typedef struct QuirkEntryType static QuirkEntryType quirks[] = { #if defined(__unix__) + /* freedroid use RLE-encoded surfaces, where SDL-1.2 didn't preserve destination alpha. This works around an sdl12-compat incompatibility. */ + {"freedroid", "SDL12COMPAT_PRESERVE_DEST_ALPHA", "0"}, + /* Awesomenauts uses Cg, and does weird things with the GL context. */ {"Awesomenauts.bin.x86", "SDL12COMPAT_OPENGL_SCALING", "0"}, {"Awesomenauts.bin.x86", "SDL12COMPAT_FORCE_GL_SWAPBUFFER_CONTEXT", "1"}, @@ -2194,6 +2197,7 @@ Init12VidModes(void) return 0; /* already did this. */ } + PreserveDestinationAlpha = SDL12Compat_GetHintBoolean("SDL12COMPAT_PRESERVE_DEST_ALPHA", SDL_TRUE); WantOpenGLScaling = use_fake_modes; SDL_assert(VideoModes == NULL); @@ -6346,7 +6350,7 @@ SaveDestAlpha(SDL12_Surface *src12, SDL12_Surface *dst12, SDL_Rect *dstrect20, U * In SDL2, we change the destination alpha. We have to save it off in this case, which sucks. */ Uint8 *dstalpha = NULL; - const SDL_bool save_dstalpha = ((src12->flags & SDL12_SRCALPHA) && dst12->format->Amask && ((src12->format->alpha != 255) || src12->format->Amask)) ? SDL_TRUE : SDL_FALSE; + const SDL_bool save_dstalpha = (PreserveDestinationAlpha && (src12->flags & SDL12_SRCALPHA) && dst12->format->Amask && ((src12->format->alpha != 255) || src12->format->Amask)) ? SDL_TRUE : SDL_FALSE; if (save_dstalpha && (dstrect20->w > 0) && (dstrect20->h > 0)) { const Uint32 amask = dst12->format->Amask; From 59e3eb95ab01e54da012d4514122dd83ef231d07 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 18 May 2023 09:11:20 -0400 Subject: [PATCH 454/606] version: Bumping to 1.2.62 for release candidate. (Actual release will bump to 1.2.64, and then revision control will go to 1.2.65 for work, next release candidate will be 1.2.66, then 1.2.68, etc.) --- CMakeLists.txt | 4 ++-- include/SDL/SDL_version.h | 2 +- src/Makefile.darwin | 2 +- src/Makefile.linux | 2 +- src/Makefile.os2 | 2 +- src/Makefile.w32 | 2 +- src/SDL12_compat.c | 2 +- src/version.rc | 8 ++++---- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9ed261242..4e4be6f48 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.0.0) project(sdl12_compat - VERSION 1.2.61 + VERSION 1.2.62 LANGUAGES C) option(SDL12TESTS "Enable to build SDL-1.2 test programs" ON) @@ -33,7 +33,7 @@ if(APPLE) # Xcode project file uses 1.0.0, but it's more compatible to use the # higher version. set(DYLIB_COMPAT_VERSION 12.0.0 CACHE STRING "library compatibility version") - set(DYLIB_CURRENT_VERSION 12.61.0 CACHE STRING "library current version") + set(DYLIB_CURRENT_VERSION 12.62.0 CACHE STRING "library current version") include_directories("/opt/X11/include") # hack. if(CMAKE_VERSION VERSION_LESS 3.9) else() diff --git a/include/SDL/SDL_version.h b/include/SDL/SDL_version.h index e74508788..12abc14f4 100644 --- a/include/SDL/SDL_version.h +++ b/include/SDL/SDL_version.h @@ -33,7 +33,7 @@ real SDL-1.2 available to you. */ /* We bumped the patchlevel to 50 for sdl12-compat */ #define SDL_MAJOR_VERSION 1 #define SDL_MINOR_VERSION 2 -#define SDL_PATCHLEVEL 61 +#define SDL_PATCHLEVEL 62 typedef struct SDL_version { diff --git a/src/Makefile.darwin b/src/Makefile.darwin index 6d48386ef..3435e0fd2 100644 --- a/src/Makefile.darwin +++ b/src/Makefile.darwin @@ -18,7 +18,7 @@ CFLAGS = -mmacosx-version-min=10.6 -fPIC -O3 -Wall LDFLAGS = -mmacosx-version-min=10.6 -dynamiclib -Wl,-undefined,error -Wl,-single_module #LDFLAGS+= -Wl,-headerpad_max_install_names LDFLAGS+= -Wl,-install_name,"/usr/local/lib/$(DYLIB)" -LDFLAGS+= -Wl,-compatibility_version,1.0 -Wl,-current_version,12.61 +LDFLAGS+= -Wl,-compatibility_version,1.0 -Wl,-current_version,12.62 LDLIBS = -Wl,-framework,AppKit # this is needed for x86_64 - cross-gcc might not add it. #LDLIBS += -Wl,-lbundle1.o diff --git a/src/Makefile.linux b/src/Makefile.linux index 970f47b5c..82c83c6e7 100644 --- a/src/Makefile.linux +++ b/src/Makefile.linux @@ -16,7 +16,7 @@ LDFLAGS = -shared -Wl,-soname,libSDL-1.2.so.0 LDFLAGS+= -Wl,--no-undefined LDLIBS = -ldl -SHLIB = libSDL-1.2.so.1.2.61 +SHLIB = libSDL-1.2.so.1.2.62 OBJ = SDL12_compat.o diff --git a/src/Makefile.os2 b/src/Makefile.os2 index 8102655e5..6d8d63eef 100644 --- a/src/Makefile.os2 +++ b/src/Makefile.os2 @@ -5,7 +5,7 @@ !endif DLLNAME = SDL12 -VERSION = 1.2.61 +VERSION = 1.2.62 # change SDL2INC to point to the SDL2 headers SDL2INC = include diff --git a/src/Makefile.w32 b/src/Makefile.w32 index 2c3e4f639..7e8c47677 100644 --- a/src/Makefile.w32 +++ b/src/Makefile.w32 @@ -5,7 +5,7 @@ !endif DLLNAME = SDL -VERSION = 1.2.61 +VERSION = 1.2.62 # change SDL2INC to point to the SDL2 headers SDL2INC = include diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index cea627a84..23997e7db 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -28,7 +28,7 @@ * should be way ahead of what SDL-1.2 Classic would report, so apps can * decide if they're running under the compat layer, if they really care. */ -#define SDL12_COMPAT_VERSION 61 +#define SDL12_COMPAT_VERSION 62 #include #include diff --git a/src/version.rc b/src/version.rc index 158b04b4e..fb9f65376 100644 --- a/src/version.rc +++ b/src/version.rc @@ -3,8 +3,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,2,61,0 - PRODUCTVERSION 1,2,61,0 + FILEVERSION 1,2,62,0 + PRODUCTVERSION 1,2,62,0 FILEFLAGSMASK 0x3fL FILEFLAGS 0x0L FILEOS 0x40004L @@ -17,12 +17,12 @@ BEGIN BEGIN VALUE "CompanyName", "\0" VALUE "FileDescription", "SDL\0" - VALUE "FileVersion", "1, 2, 61, 0\0" + VALUE "FileVersion", "1, 2, 62, 0\0" VALUE "InternalName", "SDL\0" VALUE "LegalCopyright", "Copyright (C) 2022 Sam Lantinga\0" VALUE "OriginalFilename", "SDL.dll\0" VALUE "ProductName", "Simple DirectMedia Layer 1.2 wrapper\0" - VALUE "ProductVersion", "1, 2, 61, 0\0" + VALUE "ProductVersion", "1, 2, 62, 0\0" END END BLOCK "VarFileInfo" From dcb3af3cab4d36834f4b2492df4bc5dde9a773f7 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 18 May 2023 09:42:15 -0400 Subject: [PATCH 455/606] Bumped version to 1.2.63 for future development towards a 1.2.64 release. --- CMakeLists.txt | 4 ++-- include/SDL/SDL_version.h | 2 +- src/Makefile.darwin | 2 +- src/Makefile.linux | 2 +- src/Makefile.os2 | 2 +- src/Makefile.w32 | 2 +- src/SDL12_compat.c | 2 +- src/version.rc | 8 ++++---- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4e4be6f48..99fd8b3cd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.0.0) project(sdl12_compat - VERSION 1.2.62 + VERSION 1.2.63 LANGUAGES C) option(SDL12TESTS "Enable to build SDL-1.2 test programs" ON) @@ -33,7 +33,7 @@ if(APPLE) # Xcode project file uses 1.0.0, but it's more compatible to use the # higher version. set(DYLIB_COMPAT_VERSION 12.0.0 CACHE STRING "library compatibility version") - set(DYLIB_CURRENT_VERSION 12.62.0 CACHE STRING "library current version") + set(DYLIB_CURRENT_VERSION 12.63.0 CACHE STRING "library current version") include_directories("/opt/X11/include") # hack. if(CMAKE_VERSION VERSION_LESS 3.9) else() diff --git a/include/SDL/SDL_version.h b/include/SDL/SDL_version.h index 12abc14f4..9fb18fde9 100644 --- a/include/SDL/SDL_version.h +++ b/include/SDL/SDL_version.h @@ -33,7 +33,7 @@ real SDL-1.2 available to you. */ /* We bumped the patchlevel to 50 for sdl12-compat */ #define SDL_MAJOR_VERSION 1 #define SDL_MINOR_VERSION 2 -#define SDL_PATCHLEVEL 62 +#define SDL_PATCHLEVEL 63 typedef struct SDL_version { diff --git a/src/Makefile.darwin b/src/Makefile.darwin index 3435e0fd2..717bfc24d 100644 --- a/src/Makefile.darwin +++ b/src/Makefile.darwin @@ -18,7 +18,7 @@ CFLAGS = -mmacosx-version-min=10.6 -fPIC -O3 -Wall LDFLAGS = -mmacosx-version-min=10.6 -dynamiclib -Wl,-undefined,error -Wl,-single_module #LDFLAGS+= -Wl,-headerpad_max_install_names LDFLAGS+= -Wl,-install_name,"/usr/local/lib/$(DYLIB)" -LDFLAGS+= -Wl,-compatibility_version,1.0 -Wl,-current_version,12.62 +LDFLAGS+= -Wl,-compatibility_version,1.0 -Wl,-current_version,12.63 LDLIBS = -Wl,-framework,AppKit # this is needed for x86_64 - cross-gcc might not add it. #LDLIBS += -Wl,-lbundle1.o diff --git a/src/Makefile.linux b/src/Makefile.linux index 82c83c6e7..e5862eb4b 100644 --- a/src/Makefile.linux +++ b/src/Makefile.linux @@ -16,7 +16,7 @@ LDFLAGS = -shared -Wl,-soname,libSDL-1.2.so.0 LDFLAGS+= -Wl,--no-undefined LDLIBS = -ldl -SHLIB = libSDL-1.2.so.1.2.62 +SHLIB = libSDL-1.2.so.1.2.63 OBJ = SDL12_compat.o diff --git a/src/Makefile.os2 b/src/Makefile.os2 index 6d8d63eef..102fee279 100644 --- a/src/Makefile.os2 +++ b/src/Makefile.os2 @@ -5,7 +5,7 @@ !endif DLLNAME = SDL12 -VERSION = 1.2.62 +VERSION = 1.2.63 # change SDL2INC to point to the SDL2 headers SDL2INC = include diff --git a/src/Makefile.w32 b/src/Makefile.w32 index 7e8c47677..a0209283c 100644 --- a/src/Makefile.w32 +++ b/src/Makefile.w32 @@ -5,7 +5,7 @@ !endif DLLNAME = SDL -VERSION = 1.2.62 +VERSION = 1.2.63 # change SDL2INC to point to the SDL2 headers SDL2INC = include diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 23997e7db..b17f73859 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -28,7 +28,7 @@ * should be way ahead of what SDL-1.2 Classic would report, so apps can * decide if they're running under the compat layer, if they really care. */ -#define SDL12_COMPAT_VERSION 62 +#define SDL12_COMPAT_VERSION 63 #include #include diff --git a/src/version.rc b/src/version.rc index fb9f65376..6f54cd8d4 100644 --- a/src/version.rc +++ b/src/version.rc @@ -3,8 +3,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,2,62,0 - PRODUCTVERSION 1,2,62,0 + FILEVERSION 1,2,63,0 + PRODUCTVERSION 1,2,63,0 FILEFLAGSMASK 0x3fL FILEFLAGS 0x0L FILEOS 0x40004L @@ -17,12 +17,12 @@ BEGIN BEGIN VALUE "CompanyName", "\0" VALUE "FileDescription", "SDL\0" - VALUE "FileVersion", "1, 2, 62, 0\0" + VALUE "FileVersion", "1, 2, 63, 0\0" VALUE "InternalName", "SDL\0" VALUE "LegalCopyright", "Copyright (C) 2022 Sam Lantinga\0" VALUE "OriginalFilename", "SDL.dll\0" VALUE "ProductName", "Simple DirectMedia Layer 1.2 wrapper\0" - VALUE "ProductVersion", "1, 2, 62, 0\0" + VALUE "ProductVersion", "1, 2, 63, 0\0" END END BLOCK "VarFileInfo" From 3d54d076074c8fa1d5ea80e1b550901c545e2552 Mon Sep 17 00:00:00 2001 From: David Gow Date: Fri, 19 May 2023 21:03:18 +0800 Subject: [PATCH 456/606] COMPATIBILITY.md: Add a note for Civilization: Call to Power This is the old Loki port, as described in issue #176. It's mostly just a link to my website, where's there's an exhaustive (and exhausting) page which describes all the hacks needed to get the game working. --- COMPATIBILITY.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/COMPATIBILITY.md b/COMPATIBILITY.md index e99ba6b64..f518b5ce3 100644 --- a/COMPATIBILITY.md +++ b/COMPATIBILITY.md @@ -110,3 +110,20 @@ name and the game isn't working, try this environment variable: export SDL12COMPAT_NO_QUIT_VIDEO=1 +## Civilization: Call to Power (Linux) + +The Linux port of Civilization: Call to Power is very old, and has a number +of issues running on modern systems. The relevant ones for sdl12-compat are +that the game uses SDL 1.1 (not SDL 1.2), and that it uses CD audio. + +To fix the former, you'll need to either rename the sdl12-compat files, or +patch the game binary to look for libSDL-1.2.so.0. + +For the latter, you'll need to rip the game's CD audio, and set the +SDL12COMPAT_FAKE_CDROM_PATH environment variable. Make sure you set this to an +absolute path, as the game changes directories before initializing SDL. + +A more complete guide for getting the game to work on modern systems with +sdl12-compat is available [here](https://davidgow.net/hacks/civctp.html). + +(Some of these tricks may also work for other old Loki Entertainment ports, too.) From 32a06ea1f13a1e516a2e0f8e0dcf266fa1d88ada Mon Sep 17 00:00:00 2001 From: David Gow Date: Fri, 19 May 2023 21:36:03 +0800 Subject: [PATCH 457/606] SysWW/X11: Return the X11 window as wmwindow and x11window Steel Storm (and presumably other darkplaces, SDL 1.2-based games) expect x11.wmwindow to be valid if they've created a window and are running under X11. Just pass the same game window like we do for x11.window. See the old darkplaces code here: https://github.com/xonotic/darkplaces/blob/a0465ad2ee16719587b0b7a80d4c1c2f7df1ac0e/vid_sdl.c#L2334 This should fix the BadWindow errors on Steel Storm Burning Retribution (issue #290) --- src/SDL12_compat.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index b17f73859..a17c503b5 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -7439,8 +7439,9 @@ SDL_GetWMInfo(SDL12_SysWMinfo *info12) info12->info.x11.display = info20.info.x11.display; info12->info.x11.window = temp_window ? 0 : info20.info.x11.window; if (SDL_VERSIONNUM(info12->version.major, info12->version.minor, info12->version.patch) >= SDL_VERSIONNUM(1, 0, 2)) { - info12->info.x11.fswindow = 0; /* these don't exist in SDL2. */ - info12->info.x11.wmwindow = 0; + /* While these don't exist in SDL2, some programs expect to get a valid window anyway. */ + info12->info.x11.fswindow = temp_window ? 0 : info20.info.x11.window; + info12->info.x11.wmwindow = temp_window ? 0 : info20.info.x11.window; } if (SDL_VERSIONNUM(info12->version.major, info12->version.minor, info12->version.patch) >= SDL_VERSIONNUM(1, 2, 12)) { info12->info.x11.gfxdisplay = info20.info.x11.display; /* shrug */ From 4c22ab5714480f89ef1e8a55719d796ab51a55b0 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 19 May 2023 10:18:45 -0400 Subject: [PATCH 458/606] syswm: simplified x11.fswindow and x11.wmwindow assignments. Reference PR #292. --- src/SDL12_compat.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index a17c503b5..a69eb74fe 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -7440,8 +7440,8 @@ SDL_GetWMInfo(SDL12_SysWMinfo *info12) info12->info.x11.window = temp_window ? 0 : info20.info.x11.window; if (SDL_VERSIONNUM(info12->version.major, info12->version.minor, info12->version.patch) >= SDL_VERSIONNUM(1, 0, 2)) { /* While these don't exist in SDL2, some programs expect to get a valid window anyway. */ - info12->info.x11.fswindow = temp_window ? 0 : info20.info.x11.window; - info12->info.x11.wmwindow = temp_window ? 0 : info20.info.x11.window; + info12->info.x11.fswindow = info20.info.x11.window; + info12->info.x11.wmwindow = info20.info.x11.window; } if (SDL_VERSIONNUM(info12->version.major, info12->version.minor, info12->version.patch) >= SDL_VERSIONNUM(1, 2, 12)) { info12->info.x11.gfxdisplay = info20.info.x11.display; /* shrug */ From 2f23ad90cc55b0a6c377aeb71427d01cf622e748 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 19 May 2023 13:36:00 -0400 Subject: [PATCH 459/606] syswm: Fixed assignment of incorrect variable. Reference PR #292. --- src/SDL12_compat.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index a69eb74fe..e6146b05a 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -7440,8 +7440,8 @@ SDL_GetWMInfo(SDL12_SysWMinfo *info12) info12->info.x11.window = temp_window ? 0 : info20.info.x11.window; if (SDL_VERSIONNUM(info12->version.major, info12->version.minor, info12->version.patch) >= SDL_VERSIONNUM(1, 0, 2)) { /* While these don't exist in SDL2, some programs expect to get a valid window anyway. */ - info12->info.x11.fswindow = info20.info.x11.window; - info12->info.x11.wmwindow = info20.info.x11.window; + info12->info.x11.fswindow = info12->info.x11.window; + info12->info.x11.wmwindow = info12->info.x11.window; } if (SDL_VERSIONNUM(info12->version.major, info12->version.minor, info12->version.patch) >= SDL_VERSIONNUM(1, 2, 12)) { info12->info.x11.gfxdisplay = info20.info.x11.display; /* shrug */ From 9d4a969a7ad6f548fe4972df76fba6b62e175618 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Fri, 19 May 2023 23:50:20 +0300 Subject: [PATCH 460/606] revert MSVC x64 __cpuidex part of commit 865e832d -- not really needed. --- src/SDL12_compat.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index e6146b05a..876d2adc4 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1667,13 +1667,12 @@ SDL_revcpy(void *_dst, const void *_src, size_t len) __asm mov c, ecx \ __asm mov d, edx \ } -#elif (defined(_MSC_VER) && defined(_M_X64)) -/* Use __cpuidex instead of __cpuid because ICL does not clear ecx register */ +#elif defined(_MSC_VER) && defined(_M_X64) #include #define cpuid(func, a, b, c, d) \ { \ int CPUInfo[4]; \ - __cpuidex(CPUInfo, func, 0); \ + __cpuid(CPUInfo, func); \ a = CPUInfo[0]; \ b = CPUInfo[1]; \ c = CPUInfo[2]; \ From 4eda8abc24e29a65c6698c4e006dee9b3a6d45d3 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 25 May 2023 20:38:18 -0400 Subject: [PATCH 461/606] Bumped version to 1.2.64 for release! --- CMakeLists.txt | 4 ++-- include/SDL/SDL_version.h | 2 +- src/Makefile.darwin | 2 +- src/Makefile.linux | 2 +- src/Makefile.os2 | 2 +- src/Makefile.w32 | 2 +- src/SDL12_compat.c | 2 +- src/version.rc | 8 ++++---- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 99fd8b3cd..6015f1184 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.0.0) project(sdl12_compat - VERSION 1.2.63 + VERSION 1.2.64 LANGUAGES C) option(SDL12TESTS "Enable to build SDL-1.2 test programs" ON) @@ -33,7 +33,7 @@ if(APPLE) # Xcode project file uses 1.0.0, but it's more compatible to use the # higher version. set(DYLIB_COMPAT_VERSION 12.0.0 CACHE STRING "library compatibility version") - set(DYLIB_CURRENT_VERSION 12.63.0 CACHE STRING "library current version") + set(DYLIB_CURRENT_VERSION 12.64.0 CACHE STRING "library current version") include_directories("/opt/X11/include") # hack. if(CMAKE_VERSION VERSION_LESS 3.9) else() diff --git a/include/SDL/SDL_version.h b/include/SDL/SDL_version.h index 9fb18fde9..8fb95b591 100644 --- a/include/SDL/SDL_version.h +++ b/include/SDL/SDL_version.h @@ -33,7 +33,7 @@ real SDL-1.2 available to you. */ /* We bumped the patchlevel to 50 for sdl12-compat */ #define SDL_MAJOR_VERSION 1 #define SDL_MINOR_VERSION 2 -#define SDL_PATCHLEVEL 63 +#define SDL_PATCHLEVEL 64 typedef struct SDL_version { diff --git a/src/Makefile.darwin b/src/Makefile.darwin index 717bfc24d..c7cf7c322 100644 --- a/src/Makefile.darwin +++ b/src/Makefile.darwin @@ -18,7 +18,7 @@ CFLAGS = -mmacosx-version-min=10.6 -fPIC -O3 -Wall LDFLAGS = -mmacosx-version-min=10.6 -dynamiclib -Wl,-undefined,error -Wl,-single_module #LDFLAGS+= -Wl,-headerpad_max_install_names LDFLAGS+= -Wl,-install_name,"/usr/local/lib/$(DYLIB)" -LDFLAGS+= -Wl,-compatibility_version,1.0 -Wl,-current_version,12.63 +LDFLAGS+= -Wl,-compatibility_version,1.0 -Wl,-current_version,12.64 LDLIBS = -Wl,-framework,AppKit # this is needed for x86_64 - cross-gcc might not add it. #LDLIBS += -Wl,-lbundle1.o diff --git a/src/Makefile.linux b/src/Makefile.linux index e5862eb4b..b26ba5145 100644 --- a/src/Makefile.linux +++ b/src/Makefile.linux @@ -16,7 +16,7 @@ LDFLAGS = -shared -Wl,-soname,libSDL-1.2.so.0 LDFLAGS+= -Wl,--no-undefined LDLIBS = -ldl -SHLIB = libSDL-1.2.so.1.2.63 +SHLIB = libSDL-1.2.so.1.2.64 OBJ = SDL12_compat.o diff --git a/src/Makefile.os2 b/src/Makefile.os2 index 102fee279..0c8733c65 100644 --- a/src/Makefile.os2 +++ b/src/Makefile.os2 @@ -5,7 +5,7 @@ !endif DLLNAME = SDL12 -VERSION = 1.2.63 +VERSION = 1.2.64 # change SDL2INC to point to the SDL2 headers SDL2INC = include diff --git a/src/Makefile.w32 b/src/Makefile.w32 index a0209283c..fefe2c102 100644 --- a/src/Makefile.w32 +++ b/src/Makefile.w32 @@ -5,7 +5,7 @@ !endif DLLNAME = SDL -VERSION = 1.2.63 +VERSION = 1.2.64 # change SDL2INC to point to the SDL2 headers SDL2INC = include diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 876d2adc4..8d07936f3 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -28,7 +28,7 @@ * should be way ahead of what SDL-1.2 Classic would report, so apps can * decide if they're running under the compat layer, if they really care. */ -#define SDL12_COMPAT_VERSION 63 +#define SDL12_COMPAT_VERSION 64 #include #include diff --git a/src/version.rc b/src/version.rc index 6f54cd8d4..7771df04e 100644 --- a/src/version.rc +++ b/src/version.rc @@ -3,8 +3,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,2,63,0 - PRODUCTVERSION 1,2,63,0 + FILEVERSION 1,2,64,0 + PRODUCTVERSION 1,2,64,0 FILEFLAGSMASK 0x3fL FILEFLAGS 0x0L FILEOS 0x40004L @@ -17,12 +17,12 @@ BEGIN BEGIN VALUE "CompanyName", "\0" VALUE "FileDescription", "SDL\0" - VALUE "FileVersion", "1, 2, 63, 0\0" + VALUE "FileVersion", "1, 2, 64, 0\0" VALUE "InternalName", "SDL\0" VALUE "LegalCopyright", "Copyright (C) 2022 Sam Lantinga\0" VALUE "OriginalFilename", "SDL.dll\0" VALUE "ProductName", "Simple DirectMedia Layer 1.2 wrapper\0" - VALUE "ProductVersion", "1, 2, 63, 0\0" + VALUE "ProductVersion", "1, 2, 64, 0\0" END END BLOCK "VarFileInfo" From c3256b38160515dfbf0d7d15f7ecd9bc3407acd0 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 25 May 2023 20:39:36 -0400 Subject: [PATCH 462/606] Bumped version to 1.2.65 for future development towards a 1.2.66 release. --- CMakeLists.txt | 4 ++-- include/SDL/SDL_version.h | 2 +- src/Makefile.darwin | 2 +- src/Makefile.linux | 2 +- src/Makefile.os2 | 2 +- src/Makefile.w32 | 2 +- src/SDL12_compat.c | 2 +- src/version.rc | 8 ++++---- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6015f1184..d3bb6f6ee 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.0.0) project(sdl12_compat - VERSION 1.2.64 + VERSION 1.2.65 LANGUAGES C) option(SDL12TESTS "Enable to build SDL-1.2 test programs" ON) @@ -33,7 +33,7 @@ if(APPLE) # Xcode project file uses 1.0.0, but it's more compatible to use the # higher version. set(DYLIB_COMPAT_VERSION 12.0.0 CACHE STRING "library compatibility version") - set(DYLIB_CURRENT_VERSION 12.64.0 CACHE STRING "library current version") + set(DYLIB_CURRENT_VERSION 12.65.0 CACHE STRING "library current version") include_directories("/opt/X11/include") # hack. if(CMAKE_VERSION VERSION_LESS 3.9) else() diff --git a/include/SDL/SDL_version.h b/include/SDL/SDL_version.h index 8fb95b591..8958db69a 100644 --- a/include/SDL/SDL_version.h +++ b/include/SDL/SDL_version.h @@ -33,7 +33,7 @@ real SDL-1.2 available to you. */ /* We bumped the patchlevel to 50 for sdl12-compat */ #define SDL_MAJOR_VERSION 1 #define SDL_MINOR_VERSION 2 -#define SDL_PATCHLEVEL 64 +#define SDL_PATCHLEVEL 65 typedef struct SDL_version { diff --git a/src/Makefile.darwin b/src/Makefile.darwin index c7cf7c322..a14873332 100644 --- a/src/Makefile.darwin +++ b/src/Makefile.darwin @@ -18,7 +18,7 @@ CFLAGS = -mmacosx-version-min=10.6 -fPIC -O3 -Wall LDFLAGS = -mmacosx-version-min=10.6 -dynamiclib -Wl,-undefined,error -Wl,-single_module #LDFLAGS+= -Wl,-headerpad_max_install_names LDFLAGS+= -Wl,-install_name,"/usr/local/lib/$(DYLIB)" -LDFLAGS+= -Wl,-compatibility_version,1.0 -Wl,-current_version,12.64 +LDFLAGS+= -Wl,-compatibility_version,1.0 -Wl,-current_version,12.65 LDLIBS = -Wl,-framework,AppKit # this is needed for x86_64 - cross-gcc might not add it. #LDLIBS += -Wl,-lbundle1.o diff --git a/src/Makefile.linux b/src/Makefile.linux index b26ba5145..8aaa793a5 100644 --- a/src/Makefile.linux +++ b/src/Makefile.linux @@ -16,7 +16,7 @@ LDFLAGS = -shared -Wl,-soname,libSDL-1.2.so.0 LDFLAGS+= -Wl,--no-undefined LDLIBS = -ldl -SHLIB = libSDL-1.2.so.1.2.64 +SHLIB = libSDL-1.2.so.1.2.65 OBJ = SDL12_compat.o diff --git a/src/Makefile.os2 b/src/Makefile.os2 index 0c8733c65..f1498e120 100644 --- a/src/Makefile.os2 +++ b/src/Makefile.os2 @@ -5,7 +5,7 @@ !endif DLLNAME = SDL12 -VERSION = 1.2.64 +VERSION = 1.2.65 # change SDL2INC to point to the SDL2 headers SDL2INC = include diff --git a/src/Makefile.w32 b/src/Makefile.w32 index fefe2c102..7860d6343 100644 --- a/src/Makefile.w32 +++ b/src/Makefile.w32 @@ -5,7 +5,7 @@ !endif DLLNAME = SDL -VERSION = 1.2.64 +VERSION = 1.2.65 # change SDL2INC to point to the SDL2 headers SDL2INC = include diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 8d07936f3..633720e2d 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -28,7 +28,7 @@ * should be way ahead of what SDL-1.2 Classic would report, so apps can * decide if they're running under the compat layer, if they really care. */ -#define SDL12_COMPAT_VERSION 64 +#define SDL12_COMPAT_VERSION 65 #include #include diff --git a/src/version.rc b/src/version.rc index 7771df04e..4abe81eb6 100644 --- a/src/version.rc +++ b/src/version.rc @@ -3,8 +3,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,2,64,0 - PRODUCTVERSION 1,2,64,0 + FILEVERSION 1,2,65,0 + PRODUCTVERSION 1,2,65,0 FILEFLAGSMASK 0x3fL FILEFLAGS 0x0L FILEOS 0x40004L @@ -17,12 +17,12 @@ BEGIN BEGIN VALUE "CompanyName", "\0" VALUE "FileDescription", "SDL\0" - VALUE "FileVersion", "1, 2, 64, 0\0" + VALUE "FileVersion", "1, 2, 65, 0\0" VALUE "InternalName", "SDL\0" VALUE "LegalCopyright", "Copyright (C) 2022 Sam Lantinga\0" VALUE "OriginalFilename", "SDL.dll\0" VALUE "ProductName", "Simple DirectMedia Layer 1.2 wrapper\0" - VALUE "ProductVersion", "1, 2, 64, 0\0" + VALUE "ProductVersion", "1, 2, 65, 0\0" END END BLOCK "VarFileInfo" From 619b3d89e943405547a16ccdd68c5b6f14f9bb95 Mon Sep 17 00:00:00 2001 From: Joshua Root Date: Sat, 27 May 2023 22:27:36 +1000 Subject: [PATCH 463/606] Check for undefined TARGET_OS_* Prevents some versions of clang from erroring out like this: ``` error: 'TARGET_OS_TV' is not defined, evaluates to 0 [-Werror,-Wundef-prefix=TARGET_OS_] ``` --- include/SDL/SDL_platform.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/SDL/SDL_platform.h b/include/SDL/SDL_platform.h index 850bcca27..63149f8d8 100644 --- a/include/SDL/SDL_platform.h +++ b/include/SDL/SDL_platform.h @@ -72,11 +72,11 @@ requirement is dropped too. Send patches. :) */ /* lets us know what version of Mac OS X we're compiling on */ #include "AvailabilityMacros.h" #include "TargetConditionals.h" -#if TARGET_OS_TV +#if defined(TARGET_OS_TV) && TARGET_OS_TV #undef __TVOS__ #define __TVOS__ 1 #endif -#if TARGET_OS_IPHONE +#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE /* if compiling for iOS */ #undef __IPHONEOS__ #define __IPHONEOS__ 1 From c1eb2fecf9c5fc05e2efce0e2a135cd7474a4874 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sat, 27 May 2023 18:56:56 +0300 Subject: [PATCH 464/606] update SDL_platform.h from SDL2. --- include/SDL/SDL_platform.h | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/include/SDL/SDL_platform.h b/include/SDL/SDL_platform.h index 63149f8d8..13fb98f38 100644 --- a/include/SDL/SDL_platform.h +++ b/include/SDL/SDL_platform.h @@ -70,13 +70,34 @@ requirement is dropped too. Send patches. :) */ #if defined(__APPLE__) /* lets us know what version of Mac OS X we're compiling on */ -#include "AvailabilityMacros.h" -#include "TargetConditionals.h" -#if defined(TARGET_OS_TV) && TARGET_OS_TV +#include +#include + +/* Fix building with older SDKs that don't define these + See this for more information: + https://stackoverflow.com/questions/12132933/preprocessor-macro-for-os-x-targets +*/ +#ifndef TARGET_OS_MACCATALYST +#define TARGET_OS_MACCATALYST 0 +#endif +#ifndef TARGET_OS_IOS +#define TARGET_OS_IOS 0 +#endif +#ifndef TARGET_OS_IPHONE +#define TARGET_OS_IPHONE 0 +#endif +#ifndef TARGET_OS_TV +#define TARGET_OS_TV 0 +#endif +#ifndef TARGET_OS_SIMULATOR +#define TARGET_OS_SIMULATOR 0 +#endif + +#if TARGET_OS_TV #undef __TVOS__ #define __TVOS__ 1 #endif -#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE +#if TARGET_OS_IPHONE /* if compiling for iOS */ #undef __IPHONEOS__ #define __IPHONEOS__ 1 From 4d888293679a3e3652a11f864b8a52c9040910d0 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 30 May 2023 12:00:01 -0400 Subject: [PATCH 465/606] video: Correct SDL_SetPalette()'s return value. Fixes #294. --- src/SDL12_compat.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 633720e2d..5b4536a4e 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -7321,7 +7321,8 @@ SDL_SetPalette(SDL12_Surface *surface12, int flags, const SDL_Color *colors, /* we need to force the "unused" field to 255, since it's "alpha" in SDL2. */ opaquecolors = (SDL_Color *) SDL20_malloc(sizeof (SDL_Color) * ncolors); if (!opaquecolors) { - return SDL20_OutOfMemory(); + SDL20_OutOfMemory(); + return 0; } /* don't SDL_memcpy in case the 'a' field is uninitialized and upsets @@ -7333,17 +7334,17 @@ SDL_SetPalette(SDL12_Surface *surface12, int flags, const SDL_Color *colors, opaquecolors[i].a = 255; } - retval = 0; + retval = 1; /* "The return value is 1 if all colours could be set as requested, and 0 otherwise." */ if (flags & SDL12_LOGPAL) { if (SDL20_SetPaletteColors(palette20, opaquecolors, firstcolor, ncolors) < 0) { - retval = -1; + retval = 0; } } if ((flags & SDL12_PHYSPAL) && (surface12 == VideoSurface12) && VideoPhysicalPalette20) { if (SDL20_SetPaletteColors(VideoPhysicalPalette20, opaquecolors, firstcolor, ncolors) < 0) { - retval = -1; + retval = 0; } } From a291a1a4e9e853539c6830bcf1577166701a9d35 Mon Sep 17 00:00:00 2001 From: Tyler Morgan Date: Tue, 30 May 2023 18:26:00 +0200 Subject: [PATCH 466/606] video: Correct SDL_SetPalette no-op returns #294 --- src/SDL12_compat.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 5b4536a4e..996ff34a5 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -7303,16 +7303,16 @@ SDL_SetPalette(SDL12_Surface *surface12, int flags, const SDL_Color *colors, int i, retval; if (!surface12) { - return 0; /* not an error, a no-op. */ + return 1; /* not an error, a no-op. */ } if ((flags & (SDL12_LOGPAL | SDL12_PHYSPAL)) == 0) { - return 0; /* nothing to do. */ + return 1; /* nothing to do. */ } palette12 = surface12->format->palette; if (!palette12) { - return 0; /* not an error, a no-op. */ + return 1; /* not an error, a no-op. */ } palette20 = surface12->surface20->format->palette; From edf615ddbbc40eee692080f74bcf8feb99ec6b04 Mon Sep 17 00:00:00 2001 From: Tyler Morgan Date: Tue, 30 May 2023 20:08:53 +0200 Subject: [PATCH 467/606] video: Revert SDL_SetPalette no-op return change Revert incorrect change, see #294 --- src/SDL12_compat.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 996ff34a5..5b4536a4e 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -7303,16 +7303,16 @@ SDL_SetPalette(SDL12_Surface *surface12, int flags, const SDL_Color *colors, int i, retval; if (!surface12) { - return 1; /* not an error, a no-op. */ + return 0; /* not an error, a no-op. */ } if ((flags & (SDL12_LOGPAL | SDL12_PHYSPAL)) == 0) { - return 1; /* nothing to do. */ + return 0; /* nothing to do. */ } palette12 = surface12->format->palette; if (!palette12) { - return 1; /* not an error, a no-op. */ + return 0; /* not an error, a no-op. */ } palette20 = surface12->surface20->format->palette; From 4cc23ab92477ab8446a1745a7d4f202354e430a9 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sat, 10 Jun 2023 20:23:00 +0300 Subject: [PATCH 468/606] update SDL20_include_wrapper.h header after latest SDL2 additions. --- src/SDL20_include_wrapper.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/SDL20_include_wrapper.h b/src/SDL20_include_wrapper.h index 55c04d6fe..8a791727a 100644 --- a/src/SDL20_include_wrapper.h +++ b/src/SDL20_include_wrapper.h @@ -895,6 +895,8 @@ #define SDL_ResetHints IGNORE_THIS_VERSION_OF_SDL_ResetHints #define SDL_strcasestr IGNORE_THIS_VERSION_OF_SDL_strcasestr #define SDL_GDKSuspendComplete IGNORE_THIS_VERSION_OF_SDL_GDKSuspendComplete +#define SDL_HasWindowSurface IGNORE_THIS_VERSION_OF_SDL_HasWindowSurface +#define SDL_DestroyWindowSurface IGNORE_THIS_VERSION_OF_SDL_DestroyWindowSurface /* *** HACK HACK HACK: * *** Avoid including SDL_thread.h: it defines SDL_CreateThread() as a macro */ @@ -4417,6 +4419,14 @@ typedef void (__cdecl *pfnSDL_CurrentEndThread) (unsigned); #undef SDL_GDKSuspendComplete #endif +#ifdef SDL_HasWindowSurface +#undef SDL_HasWindowSurface +#endif + +#ifdef SDL_DestroyWindowSurface +#undef SDL_DestroyWindowSurface +#endif + /* undefine these macros too: */ /* redefine using SDL2_xxx, if needed. */ From 65641b54942f06c191b73726a9538763c5ead922 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Mon, 26 Jun 2023 11:18:31 +0100 Subject: [PATCH 469/606] SDL_config.h: Assume that all platforms have ISO C89 stddef.h sdl12-compat's SDL_stdinc.h includes `` if `HAVE_STDDEF_H` is defined, but until now there was nothing that would have defined that macro. In classic SDL 1.2, SDL_stdinc.h historically included this, and some games (such as Debian package 'berusky') rely on it. stddef.h is required by ISO C89, and is unconditionally included in the headers of some widely portable libraries like libdbus, so it seems safe to assume that all platforms have it (including Windows) unless we hear otherwise. Resolves: https://github.com/libsdl-org/sdl12-compat/issues/297 Signed-off-by: Simon McVittie --- include/SDL/SDL_config.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/SDL/SDL_config.h b/include/SDL/SDL_config.h index afd04806c..f62c17019 100644 --- a/include/SDL/SDL_config.h +++ b/include/SDL/SDL_config.h @@ -54,6 +54,8 @@ typedef unsigned __int64 uint64_t; #include #define HAVE_STDARG_H 1 +#define HAVE_STDDEF_H 1 + /* for now, let's try and say everything that we care about that isn't Windows has these C runtime functions available. We're trying to avoid a configure stage, though. Send patches if your platform lacks something. */ From ed188b5e24fc33190e3eeada5e26f5d295f50948 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Tue, 27 Jun 2023 11:25:46 +0100 Subject: [PATCH 470/606] include: Use `struct private_hwdata` incomplete type for API compat Classic SDL 1.2 headers traditionally had this member as a pointer to the incomplete type `struct private_hwdata`. For whatever reason (presumably a sense of completeness) the SDLmm C++ binding[1] that is bundled in Debian package 'asc' (Advanced Strategic Command) defines an accessor for it, which is declared as returning `struct private_hwdata *` and has the obvious trivial implementation[2]. Implicit conversion from `void *` to `struct private_hwdata *` is allowed in C, but not in C++, so sdl12-classic's simplification of changing this member from `struct private_hwdata *` to `void *` breaks the build for SDLmm. Arguably it's a bug that SDLmm has this accessor, because this member is for internal use by SDL and its type has no public definition, so there's no legitimate reason for third-party code to call the accessor; but it does exist, so 100% source compatibility with classic SDL 1.2 would require it to have the same type it historically had. [1] https://sourceforge.net/projects/sdlmm/ [2] https://sourceforge.net/p/sdlmm/code/HEAD/tree/trunk/SDLmm/src/sdlmm_basesurface.h#l141 Resolves: https://github.com/libsdl-org/sdl12-compat/issues/299 Signed-off-by: Simon McVittie --- include/SDL/SDL_video.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/SDL/SDL_video.h b/include/SDL/SDL_video.h index 67db72313..d9e906917 100644 --- a/include/SDL/SDL_video.h +++ b/include/SDL/SDL_video.h @@ -89,7 +89,7 @@ typedef struct SDL_Surface Uint16 pitch; void *pixels; int offset; - void *hwdata; + struct private_hwdata *hwdata; SDL_Rect clip_rect; Uint32 unused1; Uint32 locked; From be0b7f937fdf3b4c05d0e875fa2669977a12a436 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Tue, 27 Jun 2023 18:36:43 +0100 Subject: [PATCH 471/606] SDL_config: Define HAVE_MALLOC_H on glibc-based platforms Version 3.7.4 of the Freespace 2 Source Code Project is known to rely on SDL having checked for this, and won't see a declaration of malloc_usable_size() if we don't. This is a workaround for source compatibility with classic SDL 1.2: if a game wants to use functions from a particular system header file, it should be that game's responsibility to check for the header file itself. Bug-Debian: https://bugs.debian.org/1012232#58 Signed-off-by: Simon McVittie --- include/SDL/SDL_config.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/include/SDL/SDL_config.h b/include/SDL/SDL_config.h index f62c17019..96a960379 100644 --- a/include/SDL/SDL_config.h +++ b/include/SDL/SDL_config.h @@ -129,9 +129,13 @@ stage, though. Send patches if your platform lacks something. */ #endif #endif +#if defined(__GLIBC__) +/* glibc certainly includes this, send patches if your OS does too */ +#define HAVE_MALLOC_H 1 +#endif + /* things that aren't necessarily in Linux, some are MSVC C runtime, some are BSD. Send patches. */ #if 0 -#define HAVE_MALLOC_H 1 #define HAVE_BCOPY 1 #define HAVE_ATOI 1 #define HAVE_ATOF 1 From b000fdc51a7543f4067fa45dbe402ace6c738ba6 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Wed, 5 Jul 2023 17:55:32 +0300 Subject: [PATCH 472/606] sync dr_mp3 with mainstream. --- src/dr_mp3.h | 48 ++++++++++++++++++++++++++++++++++-------------- 1 file changed, 34 insertions(+), 14 deletions(-) diff --git a/src/dr_mp3.h b/src/dr_mp3.h index 6e06ec1cd..03c7d3a01 100644 --- a/src/dr_mp3.h +++ b/src/dr_mp3.h @@ -1,6 +1,6 @@ /* MP3 audio decoder. Choice of public domain or MIT-0. See license statements at the end of this file. -dr_mp3 - v0.6.34 - 2022-09-17 +dr_mp3 - v0.6.36 - 2023-06-17 David Reid - mackron@gmail.com @@ -101,12 +101,12 @@ extern "C" { #define DRMP3_VERSION_MAJOR 0 #define DRMP3_VERSION_MINOR 6 -#define DRMP3_VERSION_REVISION 34 +#define DRMP3_VERSION_REVISION 36 #define DRMP3_VERSION_STRING DRMP3_XSTRINGIFY(DRMP3_VERSION_MAJOR) "." DRMP3_XSTRINGIFY(DRMP3_VERSION_MINOR) "." DRMP3_XSTRINGIFY(DRMP3_VERSION_REVISION) #include /* For size_t. */ -/* Sized types. */ +/* Sized Types */ typedef signed char drmp3_int8; typedef unsigned char drmp3_uint8; typedef signed short drmp3_int16; @@ -139,7 +139,9 @@ typedef drmp3_uint8 drmp3_bool8; typedef drmp3_uint32 drmp3_bool32; #define DRMP3_TRUE 1 #define DRMP3_FALSE 0 +/* End Sized Types */ +/* Decorations */ #if !defined(DRMP3_API) #if defined(DRMP3_DLL) #if defined(_WIN32) @@ -169,7 +171,9 @@ typedef drmp3_uint32 drmp3_bool32; #define DRMP3_PRIVATE static #endif #endif +/* End Decorations */ +/* Result Codes */ typedef drmp3_int32 drmp3_result; #define DRMP3_SUCCESS 0 #define DRMP3_ERROR -1 /* A generic error. */ @@ -225,11 +229,12 @@ typedef drmp3_int32 drmp3_result; #define DRMP3_CANCELLED -51 #define DRMP3_MEMORY_ALREADY_MAPPED -52 #define DRMP3_AT_END -53 - +/* End Result Codes */ #define DRMP3_MAX_PCM_FRAMES_PER_MP3_FRAME 1152 #define DRMP3_MAX_SAMPLES_PER_FRAME (DRMP3_MAX_PCM_FRAMES_PER_MP3_FRAME*2) +/* Inline */ #ifdef _MSC_VER #define DRMP3_INLINE __forceinline #elif defined(__GNUC__) @@ -256,12 +261,24 @@ typedef drmp3_int32 drmp3_result; #else #define DRMP3_INLINE #endif +/* End Inline */ DRMP3_API void drmp3_version(drmp3_uint32* pMajor, drmp3_uint32* pMinor, drmp3_uint32* pRevision); DRMP3_API const char* drmp3_version_string(void); +/* Allocation Callbacks */ +typedef struct +{ + void* pUserData; + void* (* onMalloc)(size_t sz, void* pUserData); + void* (* onRealloc)(void* p, size_t sz, void* pUserData); + void (* onFree)(void* p, void* pUserData); +} drmp3_allocation_callbacks; +/* End Allocation Callbacks */ + + /* Low Level Push API ================== @@ -336,14 +353,6 @@ will be either drmp3_seek_origin_start or drmp3_seek_origin_current. */ typedef drmp3_bool32 (* drmp3_seek_proc)(void* pUserData, int offset, drmp3_seek_origin origin); -typedef struct -{ - void* pUserData; - void* (* onMalloc)(size_t sz, void* pUserData); - void* (* onRealloc)(void* p, size_t sz, void* pUserData); - void (* onFree)(void* p, void* pUserData); -} drmp3_allocation_callbacks; - typedef struct { drmp3_uint32 channels; @@ -2433,6 +2442,7 @@ DRMP3_API void drmp3dec_f32_to_s16(const float *in, drmp3_int16 *out, size_t num Main Public API ************************************************************************************************************************************************************/ +/* SIZE_MAX */ #if defined(SIZE_MAX) #define DRMP3_SIZE_MAX SIZE_MAX #else @@ -2442,6 +2452,7 @@ DRMP3_API void drmp3dec_f32_to_s16(const float *in, drmp3_int16 *out, size_t num #define DRMP3_SIZE_MAX 0xFFFFFFFF #endif #endif +/* End SIZE_MAX */ /* Options. */ #ifndef DRMP3_SEEK_LEADING_MP3_FRAMES @@ -2949,6 +2960,7 @@ DRMP3_API drmp3_bool32 drmp3_init_memory(drmp3* pMP3, const void* pData, size_t #include #include /* For wcslen(), wcsrtombs() */ +/* Errno */ /* drmp3_result_from_errno() is only used inside DR_MP3_NO_STDIO for now. Move this out if it's ever used elsewhere. */ #include static drmp3_result drmp3_result_from_errno(int e) @@ -3352,7 +3364,9 @@ static drmp3_result drmp3_result_from_errno(int e) default: return DRMP3_ERROR; } } +/* End Errno */ +/* fopen */ static drmp3_result drmp3_fopen(FILE** ppFile, const char* pFilePath, const char* pOpenMode) { #if defined(_MSC_VER) && _MSC_VER >= 1400 @@ -3508,7 +3522,7 @@ static drmp3_result drmp3_wfopen(FILE** ppFile, const wchar_t* pFilePath, const return DRMP3_SUCCESS; } - +/* End fopen */ static size_t drmp3__on_read_stdio(void* pUserData, void* pBufferOut, size_t bytesToRead) @@ -4503,6 +4517,12 @@ counts rather than sample counts. /* REVISION HISTORY ================ +v0.6.36 - 2023-06-17 + - Fix an incorrect date in revision history. No functional change. + +v0.6.35 - 2023-05-22 + - Minor code restructure. No functional change. + v0.6.34 - 2022-09-17 - Fix compilation with DJGPP. - Fix compilation when compiling with x86 with no SSE2. @@ -4804,7 +4824,7 @@ For more information, please refer to =============================================================================== ALTERNATIVE 2 - MIT No Attribution =============================================================================== -Copyright 2020 David Reid +Copyright 2023 David Reid Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in From 4aa491ec84db46d37c8903aa64d8b893cf315b73 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Wed, 26 Jul 2023 20:50:50 +0300 Subject: [PATCH 473/606] set cmake maximum policy to 3.5. hand-picked from SDL2 commit https://github.com/libsdl-org/SDL/commit/14f4fd3f11b4bc5bded6960c7c6118ea06ad86ac --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d3bb6f6ee..87f594201 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ # you can define SDL2_INCLUDE_DIR on the cmdline. For example: # cmake -DSDL2_INCLUDE_DIR=/opt/SDL2/include/SDL2 [other stuff] -cmake_minimum_required(VERSION 3.0.0) +cmake_minimum_required(VERSION 3.0.0...3.5) project(sdl12_compat VERSION 1.2.65 LANGUAGES C) @@ -16,7 +16,7 @@ if(STATICDEVEL AND NOT (CMAKE_SYSTEM_NAME MATCHES "Linux")) endif() list(APPEND CMAKE_MODULE_PATH - "${CMAKE_CURRENT_LIST_DIR}/cmake/modules" + "${CMAKE_CURRENT_LIST_DIR}/cmake/modules" ) include(CheckCSourceCompiles) From f94a1ec0069266e40843138d0c5dd2fc6d43734c Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Wed, 26 Jul 2023 20:56:32 +0300 Subject: [PATCH 474/606] update CI: - update ubuntu from 20.04 to latest. - checkout SDL2 from the SDL2 branch, instead of release-2.0.18. - update actions/checkout to v3. --- .github/workflows/main.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 1552ec640..2c1267e31 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -10,7 +10,7 @@ jobs: matrix: platform: - { name: Windows, os: windows-latest } - - { name: Linux, os: ubuntu-20.04, flags: -GNinja } + - { name: Linux, os: ubuntu-latest, flags: -GNinja } - { name: MacOS, os: macos-latest } steps: - name: Setup Linux dependencies @@ -19,14 +19,15 @@ jobs: sudo apt-get update sudo apt-get install cmake ninja-build libgl1-mesa-dev libglu1-mesa-dev - name: Get sdl12-compat sources - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Get SDL2 headers - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: libsdl-org/SDL - ref: release-2.0.18 + ref: SDL2 path: SDL2 - name: Configure CMake run: cmake -DSDL2_INCLUDE_DIR="${{ github.workspace }}/SDL2/include" -B build ${{ matrix.platform.flags }} - name: Build run: cmake --build build/ + From 9a3e5bcb0a08d6e2dacc2616ec4cb6a53e60fb17 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sun, 6 Aug 2023 14:11:10 +0300 Subject: [PATCH 475/606] update CI watcom workflow to pull the SDL2 branch. --- .github/workflows/watcom.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/watcom.yml b/.github/workflows/watcom.yml index 960487d82..0c9e6c978 100644 --- a/.github/workflows/watcom.yml +++ b/.github/workflows/watcom.yml @@ -21,7 +21,7 @@ jobs: uses: actions/checkout@v2 with: repository: libsdl-org/SDL - ref: release-2.24.0 + ref: SDL2 path: SDL2 - name: Build sdl12-compat run: | From 041cf9a8630da195bb69a552b739f0052d8c2821 Mon Sep 17 00:00:00 2001 From: Manuel Moos Date: Sun, 6 Aug 2023 17:17:43 +0200 Subject: [PATCH 476/606] Add null check to SDL_LoadWAV_RW to avoid crashes Native SDL 1.2 and 2.0 both handle SDL_LoadWAV(null,...), SDL_LoadWAV("",...) and SDL_LoadWAV(nonexistent_file,...) by returning NULL and setting an error; this check resores that behavior. Fixes https://github.com/libsdl-org/sdl12-compat/issues/310 --- src/SDL12_compat.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 5b4536a4e..192b9b7fb 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -8454,6 +8454,10 @@ SDL_LoadWAV_RW(SDL12_RWops *rwops12, int freerwops12, SDL_RWops *rwops20 = RWops12to20(rwops12); SDL_AudioSpec *retval = NULL; + if (!rwops20) { + return NULL; + } + *buf = NULL; /* SDL2's LoadWAV requires a seekable stream, but SDL 1.2 didn't, From 9150989a711261cfc3a42e1e3e12a081f209c3a2 Mon Sep 17 00:00:00 2001 From: Manuel Moos Date: Sun, 6 Aug 2023 20:48:39 +0200 Subject: [PATCH 477/606] Always fill *buf It is an out parameter and callers might be tempted to free it no matter what the main return value says. --- src/SDL12_compat.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 192b9b7fb..fba2e5642 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -8454,12 +8454,12 @@ SDL_LoadWAV_RW(SDL12_RWops *rwops12, int freerwops12, SDL_RWops *rwops20 = RWops12to20(rwops12); SDL_AudioSpec *retval = NULL; + *buf = NULL; + if (!rwops20) { return NULL; } - *buf = NULL; - /* SDL2's LoadWAV requires a seekable stream, but SDL 1.2 didn't, so if the stream appears unseekable, try to load it into a memory rwops that we _can_ seek in */ From edc708a169806c523aaf66671049a1fbe9abbf21 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sun, 6 Aug 2023 17:01:59 -0700 Subject: [PATCH 478/606] Fixed implicit memcpy() in AddVidModeToList() --- src/SDL12_compat.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index fba2e5642..ff44eee41 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -2136,8 +2136,7 @@ AddVidModeToList(VideoModeList *vmode, SDL12_Rect *mode, const Uint16 maxw, cons } vmode->modeslist12 = (SDL12_Rect *) ptr; - vmode->modeslist12[vmode->nummodes] = *mode; - + SDL20_memcpy(&vmode->modeslist12[vmode->nummodes], mode, sizeof(vmode->modeslist12[vmode->nummodes])); vmode->nummodes++; return 0; From e3a4f787f8b5093fac31ae45fc8a0c432495829d Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 15 Aug 2023 15:57:42 -0400 Subject: [PATCH 479/606] quirks: Trine (the 2011 version from Humble Bundle) can't use GL scaling. Reference Issue #313. --- src/SDL12_compat.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index ff44eee41..c10841fd3 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1281,6 +1281,10 @@ static QuirkEntryType quirks[] = { {"scorched3d", "SDL12COMPAT_OPENGL_SCALING", "0"}, {"scorched3dc", "SDL12COMPAT_OPENGL_SCALING", "0"}, + /* Trine (the old Humble Bundle version from 2011) doesn't render in-game with GL scaling enabled. */ + {"trine-bin32", "SDL12COMPAT_OPENGL_SCALING", "0"}, + {"trine-bin64", "SDL12COMPAT_OPENGL_SCALING", "0"}, + /* boswars has a bug where SDL_AudioCVT must not require extra buffer space. See Issue #232. */ {"boswars", "SDL12COMPAT_COMPATIBILITY_AUDIOCVT", "1"}, From fdd66e3eed6a422dd20d61f357ff5a2806bf8f06 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 15 Aug 2023 16:27:50 -0400 Subject: [PATCH 480/606] quirks: Add ability to force XInitThreads before main(). Fixes #313. --- src/SDL12_compat.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index c10841fd3..9b5ba459b 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1285,6 +1285,12 @@ static QuirkEntryType quirks[] = { {"trine-bin32", "SDL12COMPAT_OPENGL_SCALING", "0"}, {"trine-bin64", "SDL12COMPAT_OPENGL_SCALING", "0"}, + /* Trine (the old Humble Bundle version from 2011)'s launcher needs X11, and needs XInitThreads _before_ GTK+ gets in there. */ + {"trine-launcher32", "SDL_VIDEODRIVER", "x11"}, + {"trine-launcher32", "SDL12COMPAT_FORCE_XINITTHREADS", "1"}, + {"trine-launcher64", "SDL_VIDEODRIVER", "x11"}, + {"trine-launcher64", "SDL12COMPAT_FORCE_XINITTHREADS", "1"}, + /* boswars has a bug where SDL_AudioCVT must not require extra buffer space. See Issue #232. */ {"boswars", "SDL12COMPAT_COMPATIBILITY_AUDIOCVT", "1"}, @@ -1487,6 +1493,22 @@ LoadSDL20(void) #endif } SDL12Compat_ApplyQuirks(force_x11); /* Apply and maybe print a list of any enabled quirks. */ + + #ifdef __linux__ + { + const char *viddrv = SDL20_getenv("SDL_VIDEODRIVER"); + if (viddrv && (SDL20_strcmp(viddrv, "x11") == 0) && SDL12Compat_GetHintBoolean("SDL12COMPAT_FORCE_XINITTHREADS", SDL_TRUE)) { + void *lib = dlopen("libX11.so.6", RTLD_GLOBAL|RTLD_NOW); + if (lib) { + int (*pXInitThreads)(void) = (int(*)(void)) dlsym(lib, "XInitThreads"); + if (pXInitThreads) { + pXInitThreads(); + } + /* leave the library open, so the XInitThreads sticks. */ + } + } + } + #endif } } if (!okay) { From 119974a6e85a456066aeb7522926b92ff029580b Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Thu, 20 Jul 2023 13:58:17 +0100 Subject: [PATCH 481/606] Factor out Surface20to12InPlace This is a step towards making it possible to use the same SDL12_Surface for the video surface at all times, and only reallocating its underlying SDL 2 SDL_Surface. Signed-off-by: Simon McVittie --- src/SDL12_compat.c | 40 ++++++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 9b5ba459b..531fd73a1 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -4937,26 +4937,21 @@ Rect12to20(const SDL12_Rect *rect12, SDL_Rect *rect20) return rect20; } -static SDL12_Surface * -Surface20to12(SDL_Surface *surface20) +static SDL_bool +Surface20to12InPlace(SDL_Surface *surface20, + SDL12_Surface *surface12) { SDL_BlendMode blendmode = SDL_BLENDMODE_NONE; - SDL12_Surface *surface12 = NULL; SDL12_Palette *palette12 = NULL; SDL12_PixelFormat *format12 = NULL; Uint32 flags = 0; if (!surface20) { - return NULL; + return SDL_FALSE; } if (surface20->pitch > 65535) { SDL20_SetError("Pitch is too large"); /* can't fit to 16-bits */ - return NULL; - } - - surface12 = (SDL12_Surface *) SDL20_malloc(sizeof (SDL12_Surface)); - if (!surface12) { - goto failed; + return SDL_FALSE; } if (surface20->format->palette) { @@ -5029,12 +5024,33 @@ Surface20to12(SDL_Surface *surface20) Rect20to12(&surface20->clip_rect, &surface12->clip_rect); surface12->refcount = surface20->refcount; - return surface12; + return SDL_TRUE; failed: - SDL20_free(surface12); SDL20_free(palette12); SDL20_free(format12); + return SDL_FALSE; +} + +static SDL12_Surface * +Surface20to12(SDL_Surface *surface20) +{ + SDL12_Surface *surface12 = NULL; + + surface12 = (SDL12_Surface *) SDL20_malloc(sizeof (SDL12_Surface)); + if (!surface12) { + goto failed; + } + + SDL20_zerop(surface12); + if (!Surface20to12InPlace(surface20, surface12)) { + goto failed; + } + + return surface12; + +failed: + SDL20_free(surface12); return NULL; } From 3c2bde93d4360516b080f163fafeca78fbf33ba2 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Thu, 20 Jul 2023 14:00:08 +0100 Subject: [PATCH 482/606] Factor out FreeSurfaceContents, and handle surface20 more defensively This is a step towards making it possible to use the same SDL12_Surface for the video surface at all times, and only reallocating its underlying SDL 2 SDL_Surface. Signed-off-by: Simon McVittie --- src/SDL12_compat.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 531fd73a1..d06225124 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -2616,6 +2616,19 @@ SDL_WasInit(Uint32 sdl12flags) return InitFlags20to12(SDL20_WasInit(sdl20flags)) | extraflags; } +static void +FreeSurfaceContents(SDL12_Surface *surface12) +{ + if (surface12->surface20) { + SDL20_FreeSurface(surface12->surface20); + surface12->surface20 = NULL; + } + if (surface12->format) { + SDL20_free(surface12->format->palette); + SDL20_free(surface12->format); + surface12->format = NULL; + } +} static SDL12_Surface *EndVidModeCreate(void); static void @@ -5223,11 +5236,7 @@ SDL_FreeSurface(SDL12_Surface *surface12) surface12->refcount--; if (surface12->refcount) return; - SDL20_FreeSurface(surface12->surface20); - if (surface12->format) { - SDL20_free(surface12->format->palette); - SDL20_free(surface12->format); - } + FreeSurfaceContents(surface12); SDL20_free(surface12); } } From 13efe605cc426752dc952522a735337078e03c6c Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Thu, 20 Jul 2023 14:04:11 +0100 Subject: [PATCH 483/606] Factor out enough of SDL_CreateRGBSurface to create surfaces in-place The part before we create the SDL 1.2 surface (creating the SDL 2.0 surface) becomes CreateRGBSurface(), and the part after becomes Surface12SetMasks(). Signed-off-by: Simon McVittie --- src/SDL12_compat.c | 40 +++++++++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index d06225124..6b58078d4 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -5131,11 +5131,10 @@ SetPalette12ForMasks(SDL12_Surface *surface12, const Uint32 Rmask, const Uint32 } } -DECLSPEC12 SDL12_Surface * SDLCALL -SDL_CreateRGBSurface(Uint32 flags12, int width, int height, int depth, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask) +static SDL_Surface * +CreateRGBSurface(Uint32 flags12, int width, int height, int depth, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask) { SDL_Surface *surface20; - SDL12_Surface *surface12; /* SDL 1.2 checks this. */ if ((width >= 16384) || (height >= 65536)) { @@ -5181,21 +5180,38 @@ SDL_CreateRGBSurface(Uint32 flags12, int width, int height, int depth, Uint32 Rm surface20 = SDL20_CreateRGBSurface(0, width, height, depth, Rmask, Gmask, Bmask, Amask); } - surface12 = Surface20to12(surface20); - if (!surface12) { - SDL20_FreeSurface(surface20); - return NULL; - } - - SDL_assert((surface12->flags & ~(SDL12_SRCCOLORKEY|SDL12_SRCALPHA)) == 0); /* shouldn't have prealloc, rleaccel, or dontfree. */ + return surface20; +} +static void +Surface12SetMasks(SDL12_Surface *surface12, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask) +{ SetPalette12ForMasks(surface12, Rmask, Gmask, Bmask); if (Amask != 0) { surface12->flags |= SDL12_SRCALPHA; - SDL20_SetSurfaceBlendMode(surface20, SDL_BLENDMODE_BLEND); + SDL20_SetSurfaceBlendMode(surface12->surface20, SDL_BLENDMODE_BLEND); } +} +DECLSPEC12 SDL12_Surface * SDLCALL +SDL_CreateRGBSurface(Uint32 flags12, int width, int height, int depth, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask) +{ + SDL12_Surface *surface12; + SDL_Surface *surface20; + + surface20 = CreateRGBSurface(flags12, width, height, depth, Rmask, Gmask, Bmask, Amask); + if (!surface20) { + return NULL; + } + surface12 = Surface20to12(surface20); + if (!surface12) { + SDL20_FreeSurface(surface20); + return NULL; + } + + SDL_assert((surface12->flags & ~(SDL12_SRCCOLORKEY|SDL12_SRCALPHA)) == 0); /* shouldn't have prealloc, rleaccel, or dontfree. */ + Surface12SetMasks(surface12, Rmask, Gmask, Bmask, Amask); return surface12; } @@ -5224,6 +5240,8 @@ SDL_CreateRGBSurfaceFrom(void *pixels, int width, int height, int depth, int pit SDL_assert((surface12->flags & ~(SDL12_SRCCOLORKEY|SDL12_SRCALPHA)) == SDL12_PREALLOC); /* should _only_ have prealloc. */ + /* TODO: Is it correct that this always ignored Amask, or should it be + * using Surface12SetMasks which takes Amask into account? */ SetPalette12ForMasks(surface12, Rmask, Gmask, Bmask); return surface12; From d86a5312783e721b19be026913d0b901ee2d3822 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Thu, 20 Jul 2023 14:20:33 +0100 Subject: [PATCH 484/606] Allocate video surface object statically as a global The SDL Perl bindings incorrectly call SDL_FreeSurface() on the result of functions that return a "borrowed" pointer to the video surface, namely SDL_SetVideoMode() and SDL_GetVideoSurface(). (See https://github.com/PerlGameDev/SDL/issues/305) When we would previously have allocated or freed the video surface wrapper object, instead allocate or free its contents in-place. When checking whether the video surface exists, because we never destroy it, we must now also check whether its underlying SDL2 video surface exists. Resolves: https://github.com/libsdl-org/sdl12-compat/issues/305 Signed-off-by: Simon McVittie --- src/SDL12_compat.c | 48 +++++++++++++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 18 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 6b58078d4..0c1c4fb86 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -980,6 +980,7 @@ static SDL_Window *VideoWindow20 = NULL; static SDL_Renderer *VideoRenderer20 = NULL; static SDL_mutex *VideoRendererLock = NULL; static SDL_Texture *VideoTexture20 = NULL; +static SDL12_Surface VideoSurface12Location; static SDL12_Surface *VideoSurface12 = NULL; static SDL_Palette *VideoPhysicalPalette20 = NULL; static Uint32 VideoSurfacePresentTicks = 0; @@ -4714,7 +4715,7 @@ EventFilter20to12(void *data, SDL_Event *event20) } case SDL_MOUSEMOTION: - if (!VideoSurface12) { + if (!VideoSurface12 || !VideoSurface12->surface20) { return 1; /* we don't have a screen surface yet? Don't send this on to the app. */ } @@ -5569,11 +5570,9 @@ EndVidModeCreate(void) VideoPhysicalPalette20 = NULL; } if (VideoSurface12) { - SDL12_Surface *screen12 = VideoSurface12; SDL20_free(VideoSurface12->pixels); VideoSurface12->pixels = NULL; - VideoSurface12 = NULL; /* SDL_FreeSurface will ignore the screen surface, so NULL the global variable out. */ - SDL_FreeSurface(screen12); + FreeSurfaceContents(VideoSurface12); } if (VideoConvertSurface20) { SDL20_FreeSurface(VideoConvertSurface20); @@ -5607,16 +5606,27 @@ EndVidModeCreate(void) return NULL; } - -static SDL12_Surface * -CreateSurface12WithFormat(const int w, const int h, const Uint32 fmt) +/* Essentially the same as SDL_CreateRGBSurface, but in-place */ +static void +CreateVideoSurface(const Uint32 fmt) { Uint32 rmask, gmask, bmask, amask; int bpp; + SDL_Surface *surface20; + if (!SDL20_PixelFormatEnumToMasks(fmt, &bpp, &rmask, &gmask, &bmask, &amask)) { - return NULL; + return; } - return SDL_CreateRGBSurface(0, w, h, bpp, rmask, gmask, bmask, amask); + + SDL20_zerop(VideoSurface12); + surface20 = CreateRGBSurface(0, 0, 0, bpp, rmask, gmask, bmask, amask); + + if (!Surface20to12InPlace(surface20, VideoSurface12)) { + FreeSurfaceContents(VideoSurface12); + return; + } + + Surface12SetMasks(VideoSurface12, rmask, gmask, bmask, amask); } static SDL_Surface * @@ -5953,6 +5963,8 @@ SetVideoModeImpl(int width, int height, int bpp, Uint32 flags12) int scaled_height = height; const char *fromwin_env = NULL; + VideoSurface12 = &VideoSurface12Location; + if (flags12 & SDL12_OPENGL) { /* For now we default GL scaling to ENABLED. If an app breaks or is linked directly to glBindFramebuffer, they'll need to turn it off with this environment variable. @@ -6042,11 +6054,11 @@ SetVideoModeImpl(int width, int height, int bpp, Uint32 flags12) default: SDL20_SetError("Unsupported bits-per-pixel"); return NULL; } - SDL_assert((VideoSurface12 != NULL) == (VideoWindow20 != NULL)); + SDL_assert((VideoSurface12->surface20 != NULL) == (VideoWindow20 != NULL)); - if (VideoSurface12 && ((VideoSurface12->flags & SDL12_OPENGL) != (flags12 & SDL12_OPENGL))) { + if (VideoSurface12->surface20 && ((VideoSurface12->flags & SDL12_OPENGL) != (flags12 & SDL12_OPENGL))) { EndVidModeCreate(); /* rebuild the window if moving to/from a GL context */ - } else if (VideoSurface12 && (VideoSurface12->surface20->format->format != appfmt)) { + } else if (VideoSurface12->surface20 && (VideoSurface12->surface20->format->format != appfmt)) { EndVidModeCreate(); /* rebuild the window if changing pixel format */ } else if (VideoGLContext20) { /* SDL 1.2 (infuriatingly!) destroys the GL context on each resize in some cases, on various platforms. Try to match that. */ @@ -6188,11 +6200,11 @@ SetVideoModeImpl(int width, int height, int bpp, Uint32 flags12) SDL20_SetWindowResizable(VideoWindow20, (flags12 & SDL12_RESIZABLE) ? SDL_TRUE : SDL_FALSE); } - if (VideoSurface12) { + if (VideoSurface12->surface20) { SDL20_free(VideoSurface12->pixels); } else { - VideoSurface12 = CreateSurface12WithFormat(0, 0, appfmt); - if (!VideoSurface12) { + CreateVideoSurface(appfmt); + if (!VideoSurface12->surface20) { return EndVidModeCreate(); } } @@ -6708,7 +6720,7 @@ DECLSPEC12 SDL12_Surface * SDLCALL SDL_DisplayFormat(SDL12_Surface *surface12) { const Uint32 flags = surface12->flags & (SDL12_SRCCOLORKEY|SDL12_SRCALPHA|SDL12_RLEACCELOK); - if (!VideoSurface12) { + if (!VideoSurface12 || !VideoSurface12->surface20) { SDL20_SetError("No video mode has been set"); return NULL; } @@ -6724,7 +6736,7 @@ SDL_DisplayFormatAlpha(SDL12_Surface *surface12) SDL_PixelFormat *fmt20 = NULL; SDL12_PixelFormat fmt12; - if (!VideoSurface12) { + if (!VideoSurface12 || !VideoSurface12->surface20) { SDL20_SetError("No video mode has been set"); return NULL; } @@ -7309,7 +7321,7 @@ static void HandleInputGrab(SDL12_GrabMode mode) { /* SDL 1.2 always grabbed input if the video mode was fullscreen. */ - const SDL_bool isfullscreen = (VideoSurface12 && (VideoSurface12->flags & SDL12_FULLSCREEN)) ? SDL_TRUE : SDL_FALSE; + const SDL_bool isfullscreen = (VideoSurface12 && VideoSurface12->surface20 && (VideoSurface12->flags & SDL12_FULLSCREEN)) ? SDL_TRUE : SDL_FALSE; const SDL_bool wantgrab = (isfullscreen || (mode == SDL12_GRAB_ON)) ? SDL_TRUE : SDL_FALSE; if (VideoWindowGrabbed != wantgrab) { if (VideoWindow20) { From e64f78dd5309ac632398f19998e47c3d0307a82d Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sat, 26 Aug 2023 20:51:56 +0300 Subject: [PATCH 485/606] update SDL20_include_wrapper.h header after latest SDL2 additions. --- src/SDL20_include_wrapper.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/SDL20_include_wrapper.h b/src/SDL20_include_wrapper.h index 8a791727a..785b89e47 100644 --- a/src/SDL20_include_wrapper.h +++ b/src/SDL20_include_wrapper.h @@ -897,10 +897,12 @@ #define SDL_GDKSuspendComplete IGNORE_THIS_VERSION_OF_SDL_GDKSuspendComplete #define SDL_HasWindowSurface IGNORE_THIS_VERSION_OF_SDL_HasWindowSurface #define SDL_DestroyWindowSurface IGNORE_THIS_VERSION_OF_SDL_DestroyWindowSurface +#define SDL_GDKGetDefaultUser IGNORE_THIS_VERSION_OF_SDL_GDKGetDefaultUser + +#if defined(_WIN32) || defined(__OS2__) /* *** HACK HACK HACK: * *** Avoid including SDL_thread.h: it defines SDL_CreateThread() as a macro */ -#if defined(_WIN32) || defined(__OS2__) #define _SDL_thread_h #define SDL_thread_h_ #define SDL_PASSED_BEGINTHREAD_ENDTHREAD @@ -939,6 +941,7 @@ typedef void (__cdecl *pfnSDL_CurrentEndThread) (unsigned); #undef CreateMutex #endif /* _WIN32 */ + #ifdef SDL_BlitSurface #undef SDL_BlitSurface #endif @@ -4427,6 +4430,10 @@ typedef void (__cdecl *pfnSDL_CurrentEndThread) (unsigned); #undef SDL_DestroyWindowSurface #endif +#ifdef SDL_GDKGetDefaultUser +#undef SDL_GDKGetDefaultUser +#endif + /* undefine these macros too: */ /* redefine using SDL2_xxx, if needed. */ From 9359cfa28993dca770fd2079351c4c8029a786c2 Mon Sep 17 00:00:00 2001 From: David Gow Date: Mon, 4 Sep 2023 11:56:11 +0800 Subject: [PATCH 486/606] Quirks: Mark of the Ninja (humble bundle) needs OpenGL scaling disabled. --- src/SDL12_compat.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 0c1c4fb86..f97944f6f 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1274,6 +1274,10 @@ static QuirkEntryType quirks[] = { {"fillets", "SDL12COMPAT_ALLOW_SYSWM", "0"}, {"fillets", "SDL12COMPAT_COMPATIBILITY_AUDIOCVT", "1"}, + /* Mark of the Ninja doesn't work with OpenGL scaling */ + {"ninja-bin32", "SDL12COMPAT_OPENGL_SCALING", "0"}, + {"ninja-bin64", "SDL12COMPAT_OPENGL_SCALING", "0"}, + /* Misuses SDL_AudioCVT */ {"pink-pony", "SDL12COMPAT_COMPATIBILITY_AUDIOCVT", "1"}, {"pink-pony.bin", "SDL12COMPAT_COMPATIBILITY_AUDIOCVT", "1"}, From 0d818b0f723e9446b8319766fa2f822d274b2ca8 Mon Sep 17 00:00:00 2001 From: David Gow Date: Wed, 13 Sep 2023 21:03:10 +0800 Subject: [PATCH 487/606] Avoid SDL_GetMouseState(), which returns raw coordinates sdl12-compat tracks the mouse position in the MousePosition variable, even when we're not in relative mouse mode. We therefore don't need to call SDL20_GetMouseState() to update it before entering relative mouse mode: we already have it from the last SDL_MOUSEMOTION event, and have already applied any scaling we need. This is important, because SDL_GetMouseState() returns the _raw_ mouse coordinates, not the ones scaled by SDL_RenderSetLogicalSize(). So we end up with a mismatch. This results in a mouse offset on non-OpenGL, scaled games, like Alpha Centauri in fullscreen (see #318). We could fix this by calling SDL_RenderWindowToLogical() instead, but that complicates the codepath as we don't always have an SDL_Renderer (we might be using OpenGL), so this seems cleaner. I've tested this with SMAC (where it fixes the bug) and Wolf4SDL (which was cited in the commit which introduced this check). Both work fine. --- src/SDL12_compat.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index f97944f6f..a90ddd087 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -7294,12 +7294,6 @@ UpdateRelativeMouseMode(void) const SDL_bool enable = (VideoWindowGrabbed && VideoCursorHidden) ? SDL_TRUE : SDL_FALSE; if (MouseInputIsRelative != enable) { MouseInputIsRelative = enable; - if (MouseInputIsRelative) { - /* reset position, we'll have to track it ourselves in SDL_MOUSEMOTION events, since 1.2 - * would give you window coordinates, even in relative mode. */ - SDL20_GetMouseState(&MousePosition.x, &MousePosition.y); - AdjustOpenGLLogicalScalingPoint(&MousePosition.x, &MousePosition.y); - } SDL20_SetRelativeMouseMode(MouseInputIsRelative); } } From 41161424ac5c4f4541b093a4923bfb60350ec0a4 Mon Sep 17 00:00:00 2001 From: David Gow Date: Mon, 4 Sep 2023 22:01:49 +0800 Subject: [PATCH 488/606] Add a hint to clamp the reported screen bit depth Some games (e.g. Hyperspace Delivery Boy) only work on a 16-bit display, but request the highest bit-depth available. Add a hint which makes all queries for a mode (including the current mode, and the implicit format chosen by providng SDL_SetVideoMode() a bpp of 0) report a bit depth less than or equal to the value of SDL12COMPAT_FORCE_BPP. For example: SDL12COMPAT_FORCE_BPP=16 ./hdb There are a few interesting "features" of this implementation: - All video modes are now clamped to 32bit, which is the default value of the hint. This seems like something we'd probably want anyway, as many SDL 1.2 apps would have trouble with >32bit video modes anway (and we never properly supported them). - This is our first proper integer hint, so add an SDL_GetHintInt() function. - Split the BPP -> format conversion into its own helper function. - This doesn't clamp the bit depth of user-created surfaces, or of the screen if the application specifically requests a bit depth. It only changes defaults and reported modes. --- src/SDL12_compat.c | 56 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 43 insertions(+), 13 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index a90ddd087..0319ce557 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1396,6 +1396,18 @@ SDL12Compat_GetHintFloat(const char *name, float default_value) return (float) SDL20_atof(val); } +static int +SDL12Compat_GetHintInt(const char *name, int default_value) +{ + const char *val = SDL12Compat_GetHint(name); + + if (!val) { + return default_value; + } + + return SDL20_atoi(val); +} + static void SDL12Compat_ApplyQuirks(SDL_bool force_x11) { @@ -2029,6 +2041,21 @@ SDL_JoystickOpened(int device_index) return SDL20_AtomicGet(&JoystickList[device_index].refcount) ? 1 : 0; } +static SDL_PixelFormatEnum +BPPToPixelFormat(int bpp) +{ + #if !SDL_VERSION_ATLEAST(2,0,14) + #define SDL_PIXELFORMAT_XRGB8888 SDL_PIXELFORMAT_RGB888 + #endif + switch (bpp) { + case 8: return SDL_PIXELFORMAT_INDEX8; + case 16: return SDL_PIXELFORMAT_RGB565; + case 24: return SDL_PIXELFORMAT_BGR24; + case 32: return SDL_PIXELFORMAT_XRGB8888; + default: SDL20_SetError("Unsupported bits-per-pixel"); return SDL_PIXELFORMAT_UNKNOWN; + } +} + static SDL_PixelFormat * PixelFormat12to20(SDL_PixelFormat *format20, SDL_Palette *palette20, const SDL12_PixelFormat *format12) { @@ -2213,6 +2240,7 @@ Init12VidModes(void) { const int total = SDL20_GetNumDisplayModes(VideoDisplayIndex); const char *maxmodestr; + const int max_bpp = SDL12Compat_GetHintInt("SDL12COMPAT_MAX_BPP", 32); VideoModeList *vmode = NULL; void *ptr = NULL; int i, j; @@ -2265,6 +2293,11 @@ Init12VidModes(void) continue; /* can't fit to 16-bits for SDL12_Rect */ } + if (SDL_BITSPERPIXEL(mode.format) > max_bpp) { + /* If we see any mode > max_bpp, reduce its bpp. */ + mode.format = BPPToPixelFormat(max_bpp); + } + if (!vmode || (mode.format != vmode->format)) { /* SDL20_GetDisplayMode() sorts on bpp first. We know when to change arrays. */ ptr = (VideoModeList *) SDL20_realloc(VideoModes, sizeof (VideoModeList) * (VideoModesCount+1)); if (!ptr) { @@ -2376,6 +2409,7 @@ Init12Video(void) { const char *driver = SDL20_GetCurrentVideoDriver(); const char *scale_method_env = SDL12Compat_GetHint("SDL12COMPAT_SCALE_METHOD"); + const int max_bpp = SDL12Compat_GetHintInt("SDL12COMPAT_MAX_BPP", 32); SDL_DisplayMode mode; int i; @@ -2440,7 +2474,11 @@ Init12Video(void) SDL20_StopTextInput(); if (SDL20_GetDesktopDisplayMode(VideoDisplayIndex, &mode) == 0) { - VideoInfoVfmt20 = SDL20_AllocFormat(mode.format); + if (SDL_BITSPERPIXEL(mode.format) > max_bpp) { + VideoInfoVfmt20 = SDL20_AllocFormat(BPPToPixelFormat(max_bpp)); + } else { + VideoInfoVfmt20 = SDL20_AllocFormat(mode.format); + } VideoInfo12.vfmt = PixelFormat20to12(&VideoInfoVfmt12, &VideoInfoPalette12, VideoInfoVfmt20); VideoInfo12.current_w = mode.w; VideoInfo12.current_h = mode.h; @@ -5960,6 +5998,7 @@ SetVideoModeImpl(int width, int height, int bpp, Uint32 flags12) Uint32 appfmt; const char *vsync_env = SDL12Compat_GetHint("SDL12COMPAT_SYNC_TO_VBLANK"); float window_size_scaling = SDL12Compat_GetHintFloat("SDL12COMPAT_WINDOW_SCALING", 1.0f); + int max_bpp = SDL12Compat_GetHintInt("SDL12COMPAT_MAX_BPP", 32); SDL_bool use_gl_scaling = SDL_FALSE; SDL_bool use_highdpi = SDL_TRUE; SDL_bool fix_bordless_fs_win = SDL_TRUE; @@ -6035,28 +6074,19 @@ SetVideoModeImpl(int width, int height, int bpp, Uint32 flags12) formats, give them 16-bit and we'll convert later. Nothing in SDL 1.2 will handle > 32 bits, so clamp there, too. AND ALSO, most apps will handle 32-bits but not 24, so force around that...so basically, you can have 16 or 32 bit. */ - bpp = (bpp <= 16) ? 16 : 32; + bpp = (bpp <= 16) ? 16 : max_bpp; } if ((bpp != 8) && (bpp != 16) && (bpp != 24) && (bpp != 32)) { if (flags12 & SDL12_ANYFORMAT) { - bpp = 32; + bpp = max_bpp; } else { SDL20_SetError("Unsupported bits-per-pixel"); return NULL; } } - #if !SDL_VERSION_ATLEAST(2,0,14) - #define SDL_PIXELFORMAT_XRGB8888 SDL_PIXELFORMAT_RGB888 - #endif - switch (bpp) { - case 8: appfmt = SDL_PIXELFORMAT_INDEX8; break; - case 16: appfmt = SDL_PIXELFORMAT_RGB565; break; - case 24: appfmt = SDL_PIXELFORMAT_BGR24; break; - case 32: appfmt = SDL_PIXELFORMAT_XRGB8888; break; - default: SDL20_SetError("Unsupported bits-per-pixel"); return NULL; - } + appfmt = BPPToPixelFormat(bpp); SDL_assert((VideoSurface12->surface20 != NULL) == (VideoWindow20 != NULL)); From 52a898ddb12387f2cc9501947dd9d24e927c2c71 Mon Sep 17 00:00:00 2001 From: David Gow Date: Thu, 14 Sep 2023 21:19:00 +0800 Subject: [PATCH 489/606] Quirks: Hyperspace Delivery Boy should run in 16bpp mode The LGP port of Hyperspace Delivery Boy has broken colour keys if run in 32-bpp mode (see bug #317). This is because it relies heavily on the imprecise RGB565->RGB888 conversion in earlier SDL 1.2 versions, when running in 32-bpp mode. The game's assets are all in 565 format, and the game converts these to the screen's format on load. It then sets a colour key. This presents a problem, because: - The generic BlitNToN implementation in SDL 1.2 just shifted the values, so the resulting image was not at full range. Magenta became (F800F8). - Early versions of SDL 1.2 fell back to the BlitNToN blitter very frequently: https://github.com/libsdl-org/SDL-1.2/commit/6f4a75de61ce7fd63e14aa3207a51a767cac3a48 - So, Hyperspace Delivery Boy calls SDL_MapRGB(0xF8, 0, 0xF8) to get the colour key, then sets it on the converted surface. - In SDL 2.0, the blitters now properly do a full-range conversion, so the magenta becomes (FF00FF), which now doesn't match the hardcoded (F800F8). - That being said, in general, it's not guaranteed that SDL_MapRGB() will do the same format conversion as SDL_CovertSurface(), so the "correct" way of handling this is to set the colour key before converting, which works (albeit slowly) in SDL2: https://github.com/libsdl-org/SDL/issues/1854 - Since the conversion behaviour is different even between SDL 1.2 versions, it's not worth trying to imitate it here, so we just force the game to run in 16-bpp mode, which works fine. - (And the game's README recommends it, too.) --- src/SDL12_compat.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 0319ce557..f3ecd3bf5 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1274,6 +1274,10 @@ static QuirkEntryType quirks[] = { {"fillets", "SDL12COMPAT_ALLOW_SYSWM", "0"}, {"fillets", "SDL12COMPAT_COMPATIBILITY_AUDIOCVT", "1"}, + /* Hyperspace Delivery Boy relies on the exact imprecision of the format conversion in some + earlier versions of SDL 1.2. It also recommends 16-bit in the README, so force it. */ + {"hdb", "SDL12COMPAT_MAX_BPP", "16"}, + /* Mark of the Ninja doesn't work with OpenGL scaling */ {"ninja-bin32", "SDL12COMPAT_OPENGL_SCALING", "0"}, {"ninja-bin64", "SDL12COMPAT_OPENGL_SCALING", "0"}, From 2d9afcbb9b4f4e616ebc715d7515fd8433c9074a Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Thu, 14 Sep 2023 17:00:10 +0300 Subject: [PATCH 490/606] fix -Wsign-compare warnings. --- src/SDL12_compat.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index f3ecd3bf5..f089a6908 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -2046,7 +2046,7 @@ SDL_JoystickOpened(int device_index) } static SDL_PixelFormatEnum -BPPToPixelFormat(int bpp) +BPPToPixelFormat(unsigned bpp) { #if !SDL_VERSION_ATLEAST(2,0,14) #define SDL_PIXELFORMAT_XRGB8888 SDL_PIXELFORMAT_RGB888 @@ -2244,7 +2244,7 @@ Init12VidModes(void) { const int total = SDL20_GetNumDisplayModes(VideoDisplayIndex); const char *maxmodestr; - const int max_bpp = SDL12Compat_GetHintInt("SDL12COMPAT_MAX_BPP", 32); + const unsigned max_bpp = SDL12Compat_GetHintInt("SDL12COMPAT_MAX_BPP", 32); VideoModeList *vmode = NULL; void *ptr = NULL; int i, j; @@ -2413,7 +2413,7 @@ Init12Video(void) { const char *driver = SDL20_GetCurrentVideoDriver(); const char *scale_method_env = SDL12Compat_GetHint("SDL12COMPAT_SCALE_METHOD"); - const int max_bpp = SDL12Compat_GetHintInt("SDL12COMPAT_MAX_BPP", 32); + const unsigned max_bpp = SDL12Compat_GetHintInt("SDL12COMPAT_MAX_BPP", 32); SDL_DisplayMode mode; int i; From cd1ad69ca0f182696913000669f963e2babb714e Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 14 Sep 2023 14:31:11 -0400 Subject: [PATCH 491/606] version: Bumping to 1.2.66 for release candidate. (Actual release will bump to 1.2.68, and then revision control will go to 1.2.69 for work, next release candidate will be 1.2.70, then 1.2.72, etc.) --- CMakeLists.txt | 4 ++-- include/SDL/SDL_version.h | 2 +- src/Makefile.darwin | 2 +- src/Makefile.linux | 2 +- src/Makefile.os2 | 2 +- src/Makefile.w32 | 2 +- src/SDL12_compat.c | 2 +- src/version.rc | 8 ++++---- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 87f594201..1a6578158 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.0.0...3.5) project(sdl12_compat - VERSION 1.2.65 + VERSION 1.2.66 LANGUAGES C) option(SDL12TESTS "Enable to build SDL-1.2 test programs" ON) @@ -33,7 +33,7 @@ if(APPLE) # Xcode project file uses 1.0.0, but it's more compatible to use the # higher version. set(DYLIB_COMPAT_VERSION 12.0.0 CACHE STRING "library compatibility version") - set(DYLIB_CURRENT_VERSION 12.65.0 CACHE STRING "library current version") + set(DYLIB_CURRENT_VERSION 12.66.0 CACHE STRING "library current version") include_directories("/opt/X11/include") # hack. if(CMAKE_VERSION VERSION_LESS 3.9) else() diff --git a/include/SDL/SDL_version.h b/include/SDL/SDL_version.h index 8958db69a..c7347e6ef 100644 --- a/include/SDL/SDL_version.h +++ b/include/SDL/SDL_version.h @@ -33,7 +33,7 @@ real SDL-1.2 available to you. */ /* We bumped the patchlevel to 50 for sdl12-compat */ #define SDL_MAJOR_VERSION 1 #define SDL_MINOR_VERSION 2 -#define SDL_PATCHLEVEL 65 +#define SDL_PATCHLEVEL 66 typedef struct SDL_version { diff --git a/src/Makefile.darwin b/src/Makefile.darwin index a14873332..3c6029222 100644 --- a/src/Makefile.darwin +++ b/src/Makefile.darwin @@ -18,7 +18,7 @@ CFLAGS = -mmacosx-version-min=10.6 -fPIC -O3 -Wall LDFLAGS = -mmacosx-version-min=10.6 -dynamiclib -Wl,-undefined,error -Wl,-single_module #LDFLAGS+= -Wl,-headerpad_max_install_names LDFLAGS+= -Wl,-install_name,"/usr/local/lib/$(DYLIB)" -LDFLAGS+= -Wl,-compatibility_version,1.0 -Wl,-current_version,12.65 +LDFLAGS+= -Wl,-compatibility_version,1.0 -Wl,-current_version,12.66 LDLIBS = -Wl,-framework,AppKit # this is needed for x86_64 - cross-gcc might not add it. #LDLIBS += -Wl,-lbundle1.o diff --git a/src/Makefile.linux b/src/Makefile.linux index 8aaa793a5..86d0fe65a 100644 --- a/src/Makefile.linux +++ b/src/Makefile.linux @@ -16,7 +16,7 @@ LDFLAGS = -shared -Wl,-soname,libSDL-1.2.so.0 LDFLAGS+= -Wl,--no-undefined LDLIBS = -ldl -SHLIB = libSDL-1.2.so.1.2.65 +SHLIB = libSDL-1.2.so.1.2.66 OBJ = SDL12_compat.o diff --git a/src/Makefile.os2 b/src/Makefile.os2 index f1498e120..7de161264 100644 --- a/src/Makefile.os2 +++ b/src/Makefile.os2 @@ -5,7 +5,7 @@ !endif DLLNAME = SDL12 -VERSION = 1.2.65 +VERSION = 1.2.66 # change SDL2INC to point to the SDL2 headers SDL2INC = include diff --git a/src/Makefile.w32 b/src/Makefile.w32 index 7860d6343..f91092996 100644 --- a/src/Makefile.w32 +++ b/src/Makefile.w32 @@ -5,7 +5,7 @@ !endif DLLNAME = SDL -VERSION = 1.2.65 +VERSION = 1.2.66 # change SDL2INC to point to the SDL2 headers SDL2INC = include diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index f089a6908..2752bedad 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -28,7 +28,7 @@ * should be way ahead of what SDL-1.2 Classic would report, so apps can * decide if they're running under the compat layer, if they really care. */ -#define SDL12_COMPAT_VERSION 65 +#define SDL12_COMPAT_VERSION 66 #include #include diff --git a/src/version.rc b/src/version.rc index 4abe81eb6..4e6999e29 100644 --- a/src/version.rc +++ b/src/version.rc @@ -3,8 +3,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,2,65,0 - PRODUCTVERSION 1,2,65,0 + FILEVERSION 1,2,66,0 + PRODUCTVERSION 1,2,66,0 FILEFLAGSMASK 0x3fL FILEFLAGS 0x0L FILEOS 0x40004L @@ -17,12 +17,12 @@ BEGIN BEGIN VALUE "CompanyName", "\0" VALUE "FileDescription", "SDL\0" - VALUE "FileVersion", "1, 2, 65, 0\0" + VALUE "FileVersion", "1, 2, 66, 0\0" VALUE "InternalName", "SDL\0" VALUE "LegalCopyright", "Copyright (C) 2022 Sam Lantinga\0" VALUE "OriginalFilename", "SDL.dll\0" VALUE "ProductName", "Simple DirectMedia Layer 1.2 wrapper\0" - VALUE "ProductVersion", "1, 2, 65, 0\0" + VALUE "ProductVersion", "1, 2, 66, 0\0" END END BLOCK "VarFileInfo" From f584baa61e5c2dd2bd9c4e8cf6d4886671092a9d Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 14 Sep 2023 15:25:17 -0400 Subject: [PATCH 492/606] Bumped version to 1.2.67 for future development towards a 1.2.68 release. --- CMakeLists.txt | 4 ++-- include/SDL/SDL_version.h | 2 +- src/Makefile.darwin | 2 +- src/Makefile.linux | 2 +- src/Makefile.os2 | 2 +- src/Makefile.w32 | 2 +- src/SDL12_compat.c | 2 +- src/version.rc | 8 ++++---- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1a6578158..894ce6e65 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.0.0...3.5) project(sdl12_compat - VERSION 1.2.66 + VERSION 1.2.67 LANGUAGES C) option(SDL12TESTS "Enable to build SDL-1.2 test programs" ON) @@ -33,7 +33,7 @@ if(APPLE) # Xcode project file uses 1.0.0, but it's more compatible to use the # higher version. set(DYLIB_COMPAT_VERSION 12.0.0 CACHE STRING "library compatibility version") - set(DYLIB_CURRENT_VERSION 12.66.0 CACHE STRING "library current version") + set(DYLIB_CURRENT_VERSION 12.67.0 CACHE STRING "library current version") include_directories("/opt/X11/include") # hack. if(CMAKE_VERSION VERSION_LESS 3.9) else() diff --git a/include/SDL/SDL_version.h b/include/SDL/SDL_version.h index c7347e6ef..ef0b60209 100644 --- a/include/SDL/SDL_version.h +++ b/include/SDL/SDL_version.h @@ -33,7 +33,7 @@ real SDL-1.2 available to you. */ /* We bumped the patchlevel to 50 for sdl12-compat */ #define SDL_MAJOR_VERSION 1 #define SDL_MINOR_VERSION 2 -#define SDL_PATCHLEVEL 66 +#define SDL_PATCHLEVEL 67 typedef struct SDL_version { diff --git a/src/Makefile.darwin b/src/Makefile.darwin index 3c6029222..0432dce48 100644 --- a/src/Makefile.darwin +++ b/src/Makefile.darwin @@ -18,7 +18,7 @@ CFLAGS = -mmacosx-version-min=10.6 -fPIC -O3 -Wall LDFLAGS = -mmacosx-version-min=10.6 -dynamiclib -Wl,-undefined,error -Wl,-single_module #LDFLAGS+= -Wl,-headerpad_max_install_names LDFLAGS+= -Wl,-install_name,"/usr/local/lib/$(DYLIB)" -LDFLAGS+= -Wl,-compatibility_version,1.0 -Wl,-current_version,12.66 +LDFLAGS+= -Wl,-compatibility_version,1.0 -Wl,-current_version,12.67 LDLIBS = -Wl,-framework,AppKit # this is needed for x86_64 - cross-gcc might not add it. #LDLIBS += -Wl,-lbundle1.o diff --git a/src/Makefile.linux b/src/Makefile.linux index 86d0fe65a..7124361cf 100644 --- a/src/Makefile.linux +++ b/src/Makefile.linux @@ -16,7 +16,7 @@ LDFLAGS = -shared -Wl,-soname,libSDL-1.2.so.0 LDFLAGS+= -Wl,--no-undefined LDLIBS = -ldl -SHLIB = libSDL-1.2.so.1.2.66 +SHLIB = libSDL-1.2.so.1.2.67 OBJ = SDL12_compat.o diff --git a/src/Makefile.os2 b/src/Makefile.os2 index 7de161264..ad981befd 100644 --- a/src/Makefile.os2 +++ b/src/Makefile.os2 @@ -5,7 +5,7 @@ !endif DLLNAME = SDL12 -VERSION = 1.2.66 +VERSION = 1.2.67 # change SDL2INC to point to the SDL2 headers SDL2INC = include diff --git a/src/Makefile.w32 b/src/Makefile.w32 index f91092996..eb28d156b 100644 --- a/src/Makefile.w32 +++ b/src/Makefile.w32 @@ -5,7 +5,7 @@ !endif DLLNAME = SDL -VERSION = 1.2.66 +VERSION = 1.2.67 # change SDL2INC to point to the SDL2 headers SDL2INC = include diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 2752bedad..87b707a3c 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -28,7 +28,7 @@ * should be way ahead of what SDL-1.2 Classic would report, so apps can * decide if they're running under the compat layer, if they really care. */ -#define SDL12_COMPAT_VERSION 66 +#define SDL12_COMPAT_VERSION 67 #include #include diff --git a/src/version.rc b/src/version.rc index 4e6999e29..0b7b3f172 100644 --- a/src/version.rc +++ b/src/version.rc @@ -3,8 +3,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,2,66,0 - PRODUCTVERSION 1,2,66,0 + FILEVERSION 1,2,67,0 + PRODUCTVERSION 1,2,67,0 FILEFLAGSMASK 0x3fL FILEFLAGS 0x0L FILEOS 0x40004L @@ -17,12 +17,12 @@ BEGIN BEGIN VALUE "CompanyName", "\0" VALUE "FileDescription", "SDL\0" - VALUE "FileVersion", "1, 2, 66, 0\0" + VALUE "FileVersion", "1, 2, 67, 0\0" VALUE "InternalName", "SDL\0" VALUE "LegalCopyright", "Copyright (C) 2022 Sam Lantinga\0" VALUE "OriginalFilename", "SDL.dll\0" VALUE "ProductName", "Simple DirectMedia Layer 1.2 wrapper\0" - VALUE "ProductVersion", "1, 2, 66, 0\0" + VALUE "ProductVersion", "1, 2, 67, 0\0" END END BLOCK "VarFileInfo" From 35ef746cf1a4fde8c442dc92fe9b18c3f90d7855 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 26 Sep 2023 13:43:48 -0400 Subject: [PATCH 493/606] Bumped version to 1.2.68 for release! --- CMakeLists.txt | 4 ++-- include/SDL/SDL_version.h | 2 +- src/Makefile.darwin | 2 +- src/Makefile.linux | 2 +- src/Makefile.os2 | 2 +- src/Makefile.w32 | 2 +- src/SDL12_compat.c | 2 +- src/version.rc | 8 ++++---- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 894ce6e65..4aea54188 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.0.0...3.5) project(sdl12_compat - VERSION 1.2.67 + VERSION 1.2.68 LANGUAGES C) option(SDL12TESTS "Enable to build SDL-1.2 test programs" ON) @@ -33,7 +33,7 @@ if(APPLE) # Xcode project file uses 1.0.0, but it's more compatible to use the # higher version. set(DYLIB_COMPAT_VERSION 12.0.0 CACHE STRING "library compatibility version") - set(DYLIB_CURRENT_VERSION 12.67.0 CACHE STRING "library current version") + set(DYLIB_CURRENT_VERSION 12.68.0 CACHE STRING "library current version") include_directories("/opt/X11/include") # hack. if(CMAKE_VERSION VERSION_LESS 3.9) else() diff --git a/include/SDL/SDL_version.h b/include/SDL/SDL_version.h index ef0b60209..b1350c193 100644 --- a/include/SDL/SDL_version.h +++ b/include/SDL/SDL_version.h @@ -33,7 +33,7 @@ real SDL-1.2 available to you. */ /* We bumped the patchlevel to 50 for sdl12-compat */ #define SDL_MAJOR_VERSION 1 #define SDL_MINOR_VERSION 2 -#define SDL_PATCHLEVEL 67 +#define SDL_PATCHLEVEL 68 typedef struct SDL_version { diff --git a/src/Makefile.darwin b/src/Makefile.darwin index 0432dce48..b21881d76 100644 --- a/src/Makefile.darwin +++ b/src/Makefile.darwin @@ -18,7 +18,7 @@ CFLAGS = -mmacosx-version-min=10.6 -fPIC -O3 -Wall LDFLAGS = -mmacosx-version-min=10.6 -dynamiclib -Wl,-undefined,error -Wl,-single_module #LDFLAGS+= -Wl,-headerpad_max_install_names LDFLAGS+= -Wl,-install_name,"/usr/local/lib/$(DYLIB)" -LDFLAGS+= -Wl,-compatibility_version,1.0 -Wl,-current_version,12.67 +LDFLAGS+= -Wl,-compatibility_version,1.0 -Wl,-current_version,12.68 LDLIBS = -Wl,-framework,AppKit # this is needed for x86_64 - cross-gcc might not add it. #LDLIBS += -Wl,-lbundle1.o diff --git a/src/Makefile.linux b/src/Makefile.linux index 7124361cf..d995973f3 100644 --- a/src/Makefile.linux +++ b/src/Makefile.linux @@ -16,7 +16,7 @@ LDFLAGS = -shared -Wl,-soname,libSDL-1.2.so.0 LDFLAGS+= -Wl,--no-undefined LDLIBS = -ldl -SHLIB = libSDL-1.2.so.1.2.67 +SHLIB = libSDL-1.2.so.1.2.68 OBJ = SDL12_compat.o diff --git a/src/Makefile.os2 b/src/Makefile.os2 index ad981befd..92e6e3462 100644 --- a/src/Makefile.os2 +++ b/src/Makefile.os2 @@ -5,7 +5,7 @@ !endif DLLNAME = SDL12 -VERSION = 1.2.67 +VERSION = 1.2.68 # change SDL2INC to point to the SDL2 headers SDL2INC = include diff --git a/src/Makefile.w32 b/src/Makefile.w32 index eb28d156b..9df9a68d9 100644 --- a/src/Makefile.w32 +++ b/src/Makefile.w32 @@ -5,7 +5,7 @@ !endif DLLNAME = SDL -VERSION = 1.2.67 +VERSION = 1.2.68 # change SDL2INC to point to the SDL2 headers SDL2INC = include diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 87b707a3c..bd5825066 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -28,7 +28,7 @@ * should be way ahead of what SDL-1.2 Classic would report, so apps can * decide if they're running under the compat layer, if they really care. */ -#define SDL12_COMPAT_VERSION 67 +#define SDL12_COMPAT_VERSION 68 #include #include diff --git a/src/version.rc b/src/version.rc index 0b7b3f172..f495388da 100644 --- a/src/version.rc +++ b/src/version.rc @@ -3,8 +3,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,2,67,0 - PRODUCTVERSION 1,2,67,0 + FILEVERSION 1,2,68,0 + PRODUCTVERSION 1,2,68,0 FILEFLAGSMASK 0x3fL FILEFLAGS 0x0L FILEOS 0x40004L @@ -17,12 +17,12 @@ BEGIN BEGIN VALUE "CompanyName", "\0" VALUE "FileDescription", "SDL\0" - VALUE "FileVersion", "1, 2, 67, 0\0" + VALUE "FileVersion", "1, 2, 68, 0\0" VALUE "InternalName", "SDL\0" VALUE "LegalCopyright", "Copyright (C) 2022 Sam Lantinga\0" VALUE "OriginalFilename", "SDL.dll\0" VALUE "ProductName", "Simple DirectMedia Layer 1.2 wrapper\0" - VALUE "ProductVersion", "1, 2, 67, 0\0" + VALUE "ProductVersion", "1, 2, 68, 0\0" END END BLOCK "VarFileInfo" From 189f8f0741efdb7d6ff8308f64e5f23365d97a94 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 26 Sep 2023 13:45:10 -0400 Subject: [PATCH 494/606] Bumped version to 1.2.69 for future development towards a 1.2.70 release. --- CMakeLists.txt | 4 ++-- include/SDL/SDL_version.h | 2 +- src/Makefile.darwin | 2 +- src/Makefile.linux | 2 +- src/Makefile.os2 | 2 +- src/Makefile.w32 | 2 +- src/SDL12_compat.c | 2 +- src/version.rc | 8 ++++---- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4aea54188..89e5c562a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.0.0...3.5) project(sdl12_compat - VERSION 1.2.68 + VERSION 1.2.69 LANGUAGES C) option(SDL12TESTS "Enable to build SDL-1.2 test programs" ON) @@ -33,7 +33,7 @@ if(APPLE) # Xcode project file uses 1.0.0, but it's more compatible to use the # higher version. set(DYLIB_COMPAT_VERSION 12.0.0 CACHE STRING "library compatibility version") - set(DYLIB_CURRENT_VERSION 12.68.0 CACHE STRING "library current version") + set(DYLIB_CURRENT_VERSION 12.69.0 CACHE STRING "library current version") include_directories("/opt/X11/include") # hack. if(CMAKE_VERSION VERSION_LESS 3.9) else() diff --git a/include/SDL/SDL_version.h b/include/SDL/SDL_version.h index b1350c193..dafdf4259 100644 --- a/include/SDL/SDL_version.h +++ b/include/SDL/SDL_version.h @@ -33,7 +33,7 @@ real SDL-1.2 available to you. */ /* We bumped the patchlevel to 50 for sdl12-compat */ #define SDL_MAJOR_VERSION 1 #define SDL_MINOR_VERSION 2 -#define SDL_PATCHLEVEL 68 +#define SDL_PATCHLEVEL 69 typedef struct SDL_version { diff --git a/src/Makefile.darwin b/src/Makefile.darwin index b21881d76..ff8ca112f 100644 --- a/src/Makefile.darwin +++ b/src/Makefile.darwin @@ -18,7 +18,7 @@ CFLAGS = -mmacosx-version-min=10.6 -fPIC -O3 -Wall LDFLAGS = -mmacosx-version-min=10.6 -dynamiclib -Wl,-undefined,error -Wl,-single_module #LDFLAGS+= -Wl,-headerpad_max_install_names LDFLAGS+= -Wl,-install_name,"/usr/local/lib/$(DYLIB)" -LDFLAGS+= -Wl,-compatibility_version,1.0 -Wl,-current_version,12.68 +LDFLAGS+= -Wl,-compatibility_version,1.0 -Wl,-current_version,12.69 LDLIBS = -Wl,-framework,AppKit # this is needed for x86_64 - cross-gcc might not add it. #LDLIBS += -Wl,-lbundle1.o diff --git a/src/Makefile.linux b/src/Makefile.linux index d995973f3..88e9c26a0 100644 --- a/src/Makefile.linux +++ b/src/Makefile.linux @@ -16,7 +16,7 @@ LDFLAGS = -shared -Wl,-soname,libSDL-1.2.so.0 LDFLAGS+= -Wl,--no-undefined LDLIBS = -ldl -SHLIB = libSDL-1.2.so.1.2.68 +SHLIB = libSDL-1.2.so.1.2.69 OBJ = SDL12_compat.o diff --git a/src/Makefile.os2 b/src/Makefile.os2 index 92e6e3462..d5bb49c72 100644 --- a/src/Makefile.os2 +++ b/src/Makefile.os2 @@ -5,7 +5,7 @@ !endif DLLNAME = SDL12 -VERSION = 1.2.68 +VERSION = 1.2.69 # change SDL2INC to point to the SDL2 headers SDL2INC = include diff --git a/src/Makefile.w32 b/src/Makefile.w32 index 9df9a68d9..83c5e8ffc 100644 --- a/src/Makefile.w32 +++ b/src/Makefile.w32 @@ -5,7 +5,7 @@ !endif DLLNAME = SDL -VERSION = 1.2.68 +VERSION = 1.2.69 # change SDL2INC to point to the SDL2 headers SDL2INC = include diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index bd5825066..de76eb740 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -28,7 +28,7 @@ * should be way ahead of what SDL-1.2 Classic would report, so apps can * decide if they're running under the compat layer, if they really care. */ -#define SDL12_COMPAT_VERSION 68 +#define SDL12_COMPAT_VERSION 69 #include #include diff --git a/src/version.rc b/src/version.rc index f495388da..2df301411 100644 --- a/src/version.rc +++ b/src/version.rc @@ -3,8 +3,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,2,68,0 - PRODUCTVERSION 1,2,68,0 + FILEVERSION 1,2,69,0 + PRODUCTVERSION 1,2,69,0 FILEFLAGSMASK 0x3fL FILEFLAGS 0x0L FILEOS 0x40004L @@ -17,12 +17,12 @@ BEGIN BEGIN VALUE "CompanyName", "\0" VALUE "FileDescription", "SDL\0" - VALUE "FileVersion", "1, 2, 68, 0\0" + VALUE "FileVersion", "1, 2, 69, 0\0" VALUE "InternalName", "SDL\0" VALUE "LegalCopyright", "Copyright (C) 2022 Sam Lantinga\0" VALUE "OriginalFilename", "SDL.dll\0" VALUE "ProductName", "Simple DirectMedia Layer 1.2 wrapper\0" - VALUE "ProductVersion", "1, 2, 68, 0\0" + VALUE "ProductVersion", "1, 2, 69, 0\0" END END BLOCK "VarFileInfo" From bfc8f941eb70a57b24885f841bb05b690a659a12 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sat, 30 Sep 2023 20:56:04 +0300 Subject: [PATCH 495/606] minor warning (C4706) fix --- src/SDL12_compat.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index de76eb740..864e976cb 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -7696,7 +7696,7 @@ SDL_DisplayYUVOverlay(SDL12_Overlay *overlay12, SDL12_Rect *dstrect12) { QueuedOverlayItem *overlay; SDL12_YUVData *hwdata; - SDL_Renderer *renderer = NULL; + SDL_Renderer *renderer; const SDL_bool ThisIsSetVideoModeThread = (SDL20_ThreadID() == SetVideoModeThread) ? SDL_TRUE : SDL_FALSE; if (!overlay12) { @@ -7705,7 +7705,7 @@ SDL_DisplayYUVOverlay(SDL12_Overlay *overlay12, SDL12_Rect *dstrect12) if (!dstrect12) { return SDL20_InvalidParamError("dstrect"); } - if (!(renderer = LockVideoRenderer())) { + if ((renderer = LockVideoRenderer()) == NULL) { return SDL20_SetError("No software screen surface available"); } From 995af0f1dc5cbf7a822d2640c8def0b04dfd22f8 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 29 Nov 2023 13:23:26 -0500 Subject: [PATCH 496/606] Patched to compile against older SDL2 headers. (Headers up to the 2.0.9 release need this.) Fixes #324. --- src/SDL20_include_wrapper.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/SDL20_include_wrapper.h b/src/SDL20_include_wrapper.h index 785b89e47..083dc5ea6 100644 --- a/src/SDL20_include_wrapper.h +++ b/src/SDL20_include_wrapper.h @@ -921,6 +921,12 @@ #error You need to compile against SDL >= 2.0.7 headers. #endif +#if !SDL_VERSION_ATLEAST(2,0,10) +// SDL_PixelFormatEnum was an anonymous enum before SDL 2.0.10. +// Force it to Uint32 if compiling on older headers. +typedef Uint32 SDL_PixelFormatEnum; +#endif + /* Missing SDL_thread.h stuff (see above) */ #if defined(_WIN32) || defined(__OS2__) typedef struct SDL_Thread SDL_Thread; From 5bfdc5ec8c1c958318aa8094f0685a3330a43260 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sat, 2 Dec 2023 10:28:14 +0300 Subject: [PATCH 497/606] sync dr_mp3 with mainstream. --- src/dr_mp3.h | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/dr_mp3.h b/src/dr_mp3.h index 03c7d3a01..7dd8fa474 100644 --- a/src/dr_mp3.h +++ b/src/dr_mp3.h @@ -1,6 +1,6 @@ /* MP3 audio decoder. Choice of public domain or MIT-0. See license statements at the end of this file. -dr_mp3 - v0.6.36 - 2023-06-17 +dr_mp3 - v0.6.38 - 2023-11-02 David Reid - mackron@gmail.com @@ -101,7 +101,7 @@ extern "C" { #define DRMP3_VERSION_MAJOR 0 #define DRMP3_VERSION_MINOR 6 -#define DRMP3_VERSION_REVISION 36 +#define DRMP3_VERSION_REVISION 38 #define DRMP3_VERSION_STRING DRMP3_XSTRINGIFY(DRMP3_VERSION_MAJOR) "." DRMP3_XSTRINGIFY(DRMP3_VERSION_MINOR) "." DRMP3_XSTRINGIFY(DRMP3_VERSION_REVISION) #include /* For size_t. */ @@ -730,7 +730,7 @@ static int drmp3_have_simd(void) #endif -#if defined(__ARM_ARCH) && (__ARM_ARCH >= 6) && !defined(__aarch64__) && !defined(_M_ARM64) +#if defined(__ARM_ARCH) && (__ARM_ARCH >= 6) && !defined(__aarch64__) && !defined(_M_ARM64) && !defined(__ARM_ARCH_6M__) #define DRMP3_HAVE_ARMV6 1 static __inline__ __attribute__((always_inline)) drmp3_int32 drmp3_clip_int16_arm(drmp3_int32 a) { @@ -2719,6 +2719,11 @@ static drmp3_uint32 drmp3_decode_next_frame_ex__callbacks(drmp3* pMP3, drmp3d_sa DRMP3_ASSERT(pMP3->pData != NULL); DRMP3_ASSERT(pMP3->dataCapacity > 0); + /* Do a runtime check here to try silencing a false-positive from clang-analyzer. */ + if (pMP3->pData == NULL) { + return 0; + } + pcmFramesRead = drmp3dec_decode_frame(&pMP3->decoder, pMP3->pData + pMP3->dataConsumed, (int)pMP3->dataSize, pPCMFrames, &info); /* <-- Safe size_t -> int conversion thanks to the check above. */ /* Consume the data. */ @@ -4517,6 +4522,12 @@ counts rather than sample counts. /* REVISION HISTORY ================ +v0.6.38 - 2023-11-02 + - Fix build for ARMv6-M. + +v0.6.37 - 2023-07-07 + - Silence a static analysis warning. + v0.6.36 - 2023-06-17 - Fix an incorrect date in revision history. No functional change. From 744cfca92761747683d06147685a751691f7e13c Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Fri, 22 Dec 2023 14:56:24 +0300 Subject: [PATCH 498/606] silenced -Wunused-result for readlink(). From sdl2-compat, original patch by Sylvain Becker (@1bsyl). --- src/SDL12_compat.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 864e976cb..3d849c32f 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1318,8 +1318,10 @@ static QuirkEntryType quirks[] = { #ifdef __linux__ static void OS_GetExeName(char *buf, const unsigned maxpath) { + int ret; buf[0] = '\0'; - readlink("/proc/self/exe", buf, maxpath); + ret = readlink("/proc/self/exe", buf, maxpath); + (void)ret; } #elif defined(_WIN32) static void OS_GetExeName(char *buf, const unsigned maxpath) { From c810b6a4c41972b52c348490464332ac5f14cd3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Noel?= Date: Sun, 31 Dec 2023 14:53:31 +0100 Subject: [PATCH 499/606] cdrom: fix 'no track 1' edge case --- src/SDL12_compat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 3d849c32f..32902bfbe 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -8858,7 +8858,7 @@ SDL_CDOpen(int drive) SDL20_snprintf(fullpath, alloclen, "%s%strack%c%c.mp3", CDRomPath, DIRSEP, c0, c1); rw = SDL20_RWFromFile(fullpath, "rb"); /* if there isn't a track 1 specified, pretend it's a data track, which matches most games' needs. */ - if (!rw && (c == 0)) { + if (!rw && (c == 1)) { fake_data_track = SDL_TRUE; } } From bc081fd95e193345a821206fa205fd13411f2e3c Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Mon, 1 Jan 2024 14:14:26 +0000 Subject: [PATCH 500/606] sdl.m4: Call $PKG_CONFIG rather than hard-coding pkg-config When cross-compiling, pkg.m4 will set the PKG_CONFIG variable to a suitable pkg-config executable, which might be a host-architecture-prefixed name like aarch64-linux-gnu-pkg-config. This ensures that we will use a suitable search path that is suitable for the host architecture (the machine we are compiling for) rather than the build architecture (the machine we are compiling on) to find dependency libraries like SDL. When using pkg-config as a substitute for sdl2-config, we will similarly need to use the host-architecture-prefixed pkg-config. Setting the PKG_CONFIG environment variable is also the canonical way to request that a different pkg-config implementation be used, if that becomes necessary for some reason. Co-authored-by: Helmut Grohne Bug-Debian: https://bugs.debian.org/1059749 Signed-off-by: Simon McVittie --- sdl.m4 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sdl.m4 b/sdl.m4 index 30e1f2144..53f78896e 100644 --- a/sdl.m4 +++ b/sdl.m4 @@ -5,7 +5,7 @@ # stolen from Manish Singh # Shamelessly stolen from Owen Taylor -# serial 2 +# serial 3 dnl AM_PATH_SDL([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]]) dnl Test for SDL, and define SDL_CFLAGS and SDL_LIBS @@ -45,7 +45,7 @@ AC_ARG_ENABLE(sdltest, [ --disable-sdltest Do not try to compile and run if test "x$sdl_pc" = xyes ; then no_sdl="" - SDL_CONFIG="pkg-config sdl" + SDL_CONFIG="$PKG_CONFIG sdl" else as_save_PATH="$PATH" if test "x$prefix" != xNONE && test "$cross_compiling" != yes; then From 97e01d2bf5d50e41ed6c61c077490e3263021bcd Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Mon, 1 Jan 2024 13:45:16 -0800 Subject: [PATCH 501/606] Updated copyright for 2024 --- LICENSE.txt | 2 +- include/SDL/SDL.h | 2 +- include/SDL/SDL_active.h | 2 +- include/SDL/SDL_audio.h | 2 +- include/SDL/SDL_byteorder.h | 2 +- include/SDL/SDL_cdrom.h | 2 +- include/SDL/SDL_config.h | 2 +- include/SDL/SDL_copying.h | 2 +- include/SDL/SDL_cpuinfo.h | 2 +- include/SDL/SDL_endian.h | 2 +- include/SDL/SDL_error.h | 2 +- include/SDL/SDL_events.h | 2 +- include/SDL/SDL_getenv.h | 2 +- include/SDL/SDL_joystick.h | 2 +- include/SDL/SDL_keyboard.h | 2 +- include/SDL/SDL_keysym.h | 2 +- include/SDL/SDL_loadso.h | 2 +- include/SDL/SDL_main.h | 2 +- include/SDL/SDL_mouse.h | 2 +- include/SDL/SDL_mutex.h | 2 +- include/SDL/SDL_name.h | 2 +- include/SDL/SDL_opengl.h | 2 +- include/SDL/SDL_platform.h | 2 +- include/SDL/SDL_quit.h | 2 +- include/SDL/SDL_rwops.h | 2 +- include/SDL/SDL_stdinc.h | 2 +- include/SDL/SDL_syswm.h | 2 +- include/SDL/SDL_thread.h | 2 +- include/SDL/SDL_timer.h | 2 +- include/SDL/SDL_types.h | 2 +- include/SDL/SDL_version.h | 2 +- include/SDL/SDL_video.h | 2 +- include/SDL/begin_code.h | 2 +- include/SDL/close_code.h | 2 +- src/SDL12_compat.c | 2 +- src/SDL12_compat_objc.m | 2 +- src/SDL20_include_wrapper.h | 2 +- src/SDL20_syms.h | 2 +- src/default_cursor.h | 2 +- src/version.rc | 2 +- src/x86_msvc.h | 2 +- 41 files changed, 41 insertions(+), 41 deletions(-) diff --git a/LICENSE.txt b/LICENSE.txt index b25acf74f..a705f9b50 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,4 +1,4 @@ -Copyright (C) 1997-2023 Sam Lantinga +Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL.h b/include/SDL/SDL.h index c6021e725..1b3f0257f 100644 --- a/include/SDL/SDL.h +++ b/include/SDL/SDL.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2022 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_active.h b/include/SDL/SDL_active.h index 0d2059035..0e46ef0c0 100644 --- a/include/SDL/SDL_active.h +++ b/include/SDL/SDL_active.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2022 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_audio.h b/include/SDL/SDL_audio.h index 01de5bb08..a5a3afa17 100644 --- a/include/SDL/SDL_audio.h +++ b/include/SDL/SDL_audio.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2022 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_byteorder.h b/include/SDL/SDL_byteorder.h index a166a4d06..cbd0492e2 100644 --- a/include/SDL/SDL_byteorder.h +++ b/include/SDL/SDL_byteorder.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2022 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_cdrom.h b/include/SDL/SDL_cdrom.h index 01747ebee..1ebfdfe0c 100644 --- a/include/SDL/SDL_cdrom.h +++ b/include/SDL/SDL_cdrom.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2022 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_config.h b/include/SDL/SDL_config.h index 96a960379..407a20252 100644 --- a/include/SDL/SDL_config.h +++ b/include/SDL/SDL_config.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2022 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_copying.h b/include/SDL/SDL_copying.h index a04763a1f..7b5db740f 100644 --- a/include/SDL/SDL_copying.h +++ b/include/SDL/SDL_copying.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2022 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_cpuinfo.h b/include/SDL/SDL_cpuinfo.h index df2c598a8..4b86e56f4 100644 --- a/include/SDL/SDL_cpuinfo.h +++ b/include/SDL/SDL_cpuinfo.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2022 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_endian.h b/include/SDL/SDL_endian.h index 3c6f5c0a8..87d48ceb7 100644 --- a/include/SDL/SDL_endian.h +++ b/include/SDL/SDL_endian.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2022 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_error.h b/include/SDL/SDL_error.h index 058fd5f6d..c785de5de 100644 --- a/include/SDL/SDL_error.h +++ b/include/SDL/SDL_error.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2022 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_events.h b/include/SDL/SDL_events.h index 4d0fa8226..30915fb16 100644 --- a/include/SDL/SDL_events.h +++ b/include/SDL/SDL_events.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2022 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_getenv.h b/include/SDL/SDL_getenv.h index a27968d51..d597c9fdd 100644 --- a/include/SDL/SDL_getenv.h +++ b/include/SDL/SDL_getenv.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2022 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_joystick.h b/include/SDL/SDL_joystick.h index 31336c02d..84507bd87 100644 --- a/include/SDL/SDL_joystick.h +++ b/include/SDL/SDL_joystick.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2022 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_keyboard.h b/include/SDL/SDL_keyboard.h index 2e475b25e..3212acbea 100644 --- a/include/SDL/SDL_keyboard.h +++ b/include/SDL/SDL_keyboard.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2022 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_keysym.h b/include/SDL/SDL_keysym.h index d7e1ec3b4..7c3310fcf 100644 --- a/include/SDL/SDL_keysym.h +++ b/include/SDL/SDL_keysym.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2022 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_loadso.h b/include/SDL/SDL_loadso.h index a0497eba3..5df9471e8 100644 --- a/include/SDL/SDL_loadso.h +++ b/include/SDL/SDL_loadso.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2022 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_main.h b/include/SDL/SDL_main.h index 814134946..aa1b1acf8 100644 --- a/include/SDL/SDL_main.h +++ b/include/SDL/SDL_main.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2022 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_mouse.h b/include/SDL/SDL_mouse.h index b82e2d620..86d0ab255 100644 --- a/include/SDL/SDL_mouse.h +++ b/include/SDL/SDL_mouse.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2022 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_mutex.h b/include/SDL/SDL_mutex.h index b2a854294..709b2d8b6 100644 --- a/include/SDL/SDL_mutex.h +++ b/include/SDL/SDL_mutex.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2022 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_name.h b/include/SDL/SDL_name.h index 896d1202d..9bac06a74 100644 --- a/include/SDL/SDL_name.h +++ b/include/SDL/SDL_name.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2022 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_opengl.h b/include/SDL/SDL_opengl.h index b3ee14a07..b87477eb9 100644 --- a/include/SDL/SDL_opengl.h +++ b/include/SDL/SDL_opengl.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2022 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_platform.h b/include/SDL/SDL_platform.h index 13fb98f38..1d3480847 100644 --- a/include/SDL/SDL_platform.h +++ b/include/SDL/SDL_platform.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2022 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_quit.h b/include/SDL/SDL_quit.h index 475bbb69f..5c24c3eb9 100644 --- a/include/SDL/SDL_quit.h +++ b/include/SDL/SDL_quit.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2022 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_rwops.h b/include/SDL/SDL_rwops.h index d6a789d1d..052c23ae0 100644 --- a/include/SDL/SDL_rwops.h +++ b/include/SDL/SDL_rwops.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2022 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_stdinc.h b/include/SDL/SDL_stdinc.h index 5c62471a3..e7b3b007c 100644 --- a/include/SDL/SDL_stdinc.h +++ b/include/SDL/SDL_stdinc.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2022 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_syswm.h b/include/SDL/SDL_syswm.h index dbb2e68fa..8e6f70639 100644 --- a/include/SDL/SDL_syswm.h +++ b/include/SDL/SDL_syswm.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2022 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_thread.h b/include/SDL/SDL_thread.h index 5008ac266..b5c94e732 100644 --- a/include/SDL/SDL_thread.h +++ b/include/SDL/SDL_thread.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2022 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_timer.h b/include/SDL/SDL_timer.h index 224d62554..a1c07e365 100644 --- a/include/SDL/SDL_timer.h +++ b/include/SDL/SDL_timer.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2022 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_types.h b/include/SDL/SDL_types.h index a27968d51..d597c9fdd 100644 --- a/include/SDL/SDL_types.h +++ b/include/SDL/SDL_types.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2022 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_version.h b/include/SDL/SDL_version.h index dafdf4259..da2eda36e 100644 --- a/include/SDL/SDL_version.h +++ b/include/SDL/SDL_version.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2022 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_video.h b/include/SDL/SDL_video.h index d9e906917..bda9e55f4 100644 --- a/include/SDL/SDL_video.h +++ b/include/SDL/SDL_video.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2022 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/begin_code.h b/include/SDL/begin_code.h index f7e1693ac..f44c36069 100644 --- a/include/SDL/begin_code.h +++ b/include/SDL/begin_code.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2022 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/close_code.h b/include/SDL/close_code.h index b54c4530b..769cc5634 100644 --- a/include/SDL/close_code.h +++ b/include/SDL/close_code.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2022 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 32902bfbe..e5f80152b 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2022 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/SDL12_compat_objc.m b/src/SDL12_compat_objc.m index ca46b5ee5..25eeed757 100644 --- a/src/SDL12_compat_objc.m +++ b/src/SDL12_compat_objc.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2022 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/SDL20_include_wrapper.h b/src/SDL20_include_wrapper.h index 083dc5ea6..28eca11f1 100644 --- a/src/SDL20_include_wrapper.h +++ b/src/SDL20_include_wrapper.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2022 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/SDL20_syms.h b/src/SDL20_syms.h index 652a265d0..3d68a94e3 100644 --- a/src/SDL20_syms.h +++ b/src/SDL20_syms.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2022 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/default_cursor.h b/src/default_cursor.h index c35e98ac9..4e449059c 100644 --- a/src/default_cursor.h +++ b/src/default_cursor.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2022 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/version.rc b/src/version.rc index 2df301411..adccff915 100644 --- a/src/version.rc +++ b/src/version.rc @@ -19,7 +19,7 @@ BEGIN VALUE "FileDescription", "SDL\0" VALUE "FileVersion", "1, 2, 69, 0\0" VALUE "InternalName", "SDL\0" - VALUE "LegalCopyright", "Copyright (C) 2022 Sam Lantinga\0" + VALUE "LegalCopyright", "Copyright (C) 2024 Sam Lantinga\0" VALUE "OriginalFilename", "SDL.dll\0" VALUE "ProductName", "Simple DirectMedia Layer 1.2 wrapper\0" VALUE "ProductVersion", "1, 2, 69, 0\0" diff --git a/src/x86_msvc.h b/src/x86_msvc.h index 5d5e0ac79..4e88e4fdb 100644 --- a/src/x86_msvc.h +++ b/src/x86_msvc.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2022 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages From bb2f7ff398e3f1e75edfd7719f278e7aa4ba53d5 Mon Sep 17 00:00:00 2001 From: David Gow Date: Sun, 21 Jan 2024 21:23:12 +0800 Subject: [PATCH 502/606] README: Document SDL12COMPAT_NO_QUIT_VIDEO This hint was never documented in README.md, even though it was used in a quirk, and mentioned briefly in COMPATIBILITY.md. Fixes #329 --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 434db4069..443574245 100644 --- a/README.md +++ b/README.md @@ -269,6 +269,11 @@ The available options are: backends, because SDL 1.2 didn't have wide support for its SysWM APIs outside of Windows and X11 anyhow. +- SDL12COMPAT_NO_QUIT_VIDEO: (checked during SDL_QuitSubsystem) + If enabled, SDL_Quit() and SDL_QuitSubsystem() will never shut down the + video subsystem. This works around buggy applications which try to use + the video subsystem after shutting it down. + # Compatibility issues with OpenGL scaling From c1406185126f8e527144744a82f4bec497745bae Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Tue, 23 Apr 2024 20:37:40 +0300 Subject: [PATCH 503/606] updated SDL_endian.h and SDL_platform.h from latest SDL2 --- include/SDL/SDL_endian.h | 6 +++--- include/SDL/SDL_platform.h | 37 +++++++++++++++++++++++++++++++++++-- 2 files changed, 38 insertions(+), 5 deletions(-) diff --git a/include/SDL/SDL_endian.h b/include/SDL/SDL_endian.h index 87d48ceb7..d878e13ed 100644 --- a/include/SDL/SDL_endian.h +++ b/include/SDL/SDL_endian.h @@ -98,7 +98,7 @@ real SDL-1.2 available to you. */ #if HAS_BUILTIN_BSWAP16 #define SDL_Swap16(x) __builtin_bswap16(x) -#elif defined(_MSC_VER) && (_MSC_VER >= 1400) +#elif (defined(_MSC_VER) && (_MSC_VER >= 1400)) && !defined(__ICL) #pragma intrinsic(_byteswap_ushort) #define SDL_Swap16(x) _byteswap_ushort(x) #elif defined(__i386__) && !HAS_BROKEN_BSWAP @@ -147,7 +147,7 @@ SDL_Swap16(Uint16 x) #if HAS_BUILTIN_BSWAP32 #define SDL_Swap32(x) __builtin_bswap32(x) -#elif defined(_MSC_VER) && (_MSC_VER >= 1400) +#elif (defined(_MSC_VER) && (_MSC_VER >= 1400)) && !defined(__ICL) #pragma intrinsic(_byteswap_ulong) #define SDL_Swap32(x) _byteswap_ulong(x) #elif defined(__i386__) && !HAS_BROKEN_BSWAP @@ -199,7 +199,7 @@ SDL_Swap32(Uint32 x) #if HAS_BUILTIN_BSWAP64 #define SDL_Swap64(x) __builtin_bswap64(x) -#elif defined(_MSC_VER) && (_MSC_VER >= 1400) +#elif (defined(_MSC_VER) && (_MSC_VER >= 1400)) && !defined(__ICL) #pragma intrinsic(_byteswap_uint64) #define SDL_Swap64(x) _byteswap_uint64(x) #elif defined(__i386__) && !HAS_BROKEN_BSWAP diff --git a/include/SDL/SDL_platform.h b/include/SDL/SDL_platform.h index 1d3480847..9b27621e0 100644 --- a/include/SDL/SDL_platform.h +++ b/include/SDL/SDL_platform.h @@ -67,6 +67,10 @@ requirement is dropped too. Send patches. :) */ #undef __LINUX__ /* do we need to do this? */ #define __ANDROID__ 1 #endif +#if defined(__NGAGE__) +#undef __NGAGE__ +#define __NGAGE__ 1 +#endif #if defined(__APPLE__) /* lets us know what version of Mac OS X we're compiling on */ @@ -139,7 +143,7 @@ requirement is dropped too. Send patches. :) */ #endif #if defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) -/* Try to find out if we're compiling for WinRT or non-WinRT */ +/* Try to find out if we're compiling for WinRT, GDK or non-WinRT/GDK */ #if defined(_MSC_VER) && defined(__has_include) #if __has_include() #define HAVE_WINAPIFAMILY_H 1 @@ -161,9 +165,24 @@ requirement is dropped too. Send patches. :) */ #define WINAPI_FAMILY_WINRT 0 #endif /* HAVE_WINAPIFAMILY_H */ +#if (HAVE_WINAPIFAMILY_H) && defined(WINAPI_FAMILY_PHONE_APP) +#define SDL_WINAPI_FAMILY_PHONE (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) +#else +#define SDL_WINAPI_FAMILY_PHONE 0 +#endif + #if WINAPI_FAMILY_WINRT #undef __WINRT__ #define __WINRT__ 1 +#elif defined(_GAMING_DESKTOP) /* GDK project configuration always defines _GAMING_XXX */ +#undef __WINGDK__ +#define __WINGDK__ 1 +#elif defined(_GAMING_XBOX_XBOXONE) +#undef __XBOXONE__ +#define __XBOXONE__ 1 +#elif defined(_GAMING_XBOX_SCARLETT) +#undef __XBOXSERIES__ +#define __XBOXSERIES__ 1 #else #undef __WINDOWS__ #define __WINDOWS__ 1 @@ -174,10 +193,20 @@ requirement is dropped too. Send patches. :) */ #undef __WIN32__ #define __WIN32__ 1 #endif -#if defined(__PSP__) +/* This is to support generic "any GDK" separate from a platform-specific GDK */ +#if defined(__WINGDK__) || defined(__XBOXONE__) || defined(__XBOXSERIES__) +#undef __GDK__ +#define __GDK__ 1 +#endif +#if defined(__PSP__) || defined(__psp__) +#ifdef __PSP__ #undef __PSP__ +#endif #define __PSP__ 1 #endif +#if defined(PS2) +#define __PS2__ 1 +#endif /* The NACL compiler defines __native_client__ and __pnacl__ * Ref: http://www.chromium.org/nativeclient/pnacl/stability-of-the-pnacl-bitcode-abi @@ -199,5 +228,9 @@ requirement is dropped too. Send patches. :) */ #define __VITA__ 1 #endif +#if defined(__3DS__) +#undef __3DS__ +#define __3DS__ 1 #endif +#endif From 92ecf6440a333e715402ce995686b5a6aed5784f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Noel?= Date: Wed, 15 May 2024 15:28:37 +0200 Subject: [PATCH 504/606] quirks: Add SDL12COMPAT_COMPATIBILITY_AUDIOCVT=1 to "heroes3.dynamic". (old Loki port of Heroes of Might and Magic III) --- src/SDL12_compat.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index e5f80152b..4383a4ff6 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1303,6 +1303,9 @@ static QuirkEntryType quirks[] = { /* boswars has a bug where SDL_AudioCVT must not require extra buffer space. See Issue #232. */ {"boswars", "SDL12COMPAT_COMPATIBILITY_AUDIOCVT", "1"}, + /* Loki HOMM3 */ + {"heroes3.dynamic", "SDL12COMPAT_COMPATIBILITY_AUDIOCVT", "1"}, + /* grafx2 tries to do all sorts of stuff by talking directly to the X server, causing problems. */ {"grafx2", "SDL12COMPAT_ALLOW_SYSWM", "0"}, From e4dff16bd3a804031196f2c3264d3b6664c3fa91 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 22 May 2024 00:18:53 -0400 Subject: [PATCH 505/606] video: Always recreate the _window_, not just the GL context, like SDL 1.2. Fixes Dungeons of Dredmor (on Windows) positioning its game window weirdly after the launcher dialog is done, since it was resizing the existing window in-place instead of creating a new one and centering it. --- src/SDL12_compat.c | 41 ++++++++++++++++------------------------- 1 file changed, 16 insertions(+), 25 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 4383a4ff6..cf661e19b 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -5637,6 +5637,9 @@ EndVidModeCreate(void) OpenGLLogicalScalingFBO = 0; OpenGLLogicalScalingColor = 0; OpenGLLogicalScalingDepth = 0; + OpenGLLogicalScalingMultisampleFBO = 0; + OpenGLLogicalScalingMultisampleColor = 0; + OpenGLLogicalScalingMultisampleDepth = 0; MouseInputIsRelative = SDL_FALSE; MousePosition.x = 0; @@ -6103,10 +6106,11 @@ SetVideoModeImpl(int width, int height, int bpp, Uint32 flags12) EndVidModeCreate(); /* rebuild the window if moving to/from a GL context */ } else if (VideoSurface12->surface20 && (VideoSurface12->surface20->format->format != appfmt)) { EndVidModeCreate(); /* rebuild the window if changing pixel format */ - } else if (VideoGLContext20) { - /* SDL 1.2 (infuriatingly!) destroys the GL context on each resize in some cases, on various platforms. Try to match that. */ + } else { + SDL_assert(VideoSurface12 != NULL); + /* SDL 1.2 (infuriatingly!) destroys the window (and GL context!) on each resize in some cases, on various platforms. Try to match that. */ #ifdef __WINDOWS__ - /* The windx5 driver _always_ destroyed the GL context, unconditionally, but the default (windib) did not, so match windib. + /* The windx5 driver _always_ destroyed the window, unconditionally, but the default (windib) did not, so match windib. * windib: keep if: * - window already exists * - BitsPerPixel hasn't changed @@ -6114,16 +6118,16 @@ SetVideoModeImpl(int width, int height, int bpp, Uint32 flags12) * - window is already SDL_OPENGL. * - window is not a fullscreen window. */ - const SDL_bool destroy_gl_context = ( + const SDL_bool recreate_window = ( ((VideoSurface12->flags & ~SDL12_ANYFORMAT) != (flags12 & ~SDL12_ANYFORMAT)) || - (VideoSurface12->format->BitsPerPixel != bpp) || + (!VideoSurface12->format || (VideoSurface12->format->BitsPerPixel != bpp)) || ((flags12 & SDL12_OPENGL) != SDL12_OPENGL) || ((flags12 & SDL12_FULLSCREEN) == SDL12_FULLSCREEN) ) ? SDL_TRUE : SDL_FALSE; #elif defined(__APPLE__) - const SDL_bool destroy_gl_context = SDL_TRUE; /* macOS ("quartz" backend) unconditionally destroys the GL context */ + const SDL_bool recreate_window = SDL_TRUE; /* macOS ("quartz" backend) unconditionally destroys the GL context */ #elif defined(__HAIKU__) - const SDL_bool destroy_gl_context = SDL_FALSE; /* BeOS and Haiku ("bwindow" backend) unconditionally keeps the GL context */ + const SDL_bool recreate_window = SDL_FALSE; /* BeOS and Haiku ("bwindow" backend) unconditionally keeps the GL context */ #elif defined(__LINUX__) || defined(unix) || defined(__unix__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(sun) /* The x11 backend does in _some_ cases, and since Linux software depends on that, even though Wayland and * such wasn't a thing at the time, we treat everything that looks a little like Unix this way. @@ -6134,31 +6138,18 @@ SetVideoModeImpl(int width, int height, int bpp, Uint32 flags12) * - BitsPerPixel hasn't changed * - SDL_NOFRAME hasn't changed */ - const SDL_bool destroy_gl_context = ( + const SDL_bool recreate_window = ( ((VideoSurface12->flags & SDL12_OPENGL) != (flags12 & SDL12_OPENGL)) || ((flags12 & SDL12_OPENGL) != SDL12_OPENGL) || - (VideoSurface12->format->BitsPerPixel != bpp) || + (!VideoSurface12->format || (VideoSurface12->format->BitsPerPixel != bpp)) || ((VideoSurface12->flags & SDL12_NOFRAME) != (flags12 & SDL12_NOFRAME)) ) ? SDL_TRUE : SDL_FALSE; #else - const SDL_bool destroy_gl_context = SDL_TRUE; /* everywhere else: nuke it from orbit. Oh well. */ + const SDL_bool recreate_window = SDL_TRUE; /* everywhere else: nuke it from orbit. Oh well. */ #endif - if (destroy_gl_context) { - SDL20_GL_MakeCurrent(NULL, NULL); - SDL20_GL_DeleteContext(VideoGLContext20); - VideoGLContext20 = NULL; - SDL20_zero(OpenGLFuncs); - OpenGLBlitTexture = 0; - OpenGLBlitLockCount = 0; - OpenGLLogicalScalingWidth = 0; - OpenGLLogicalScalingHeight = 0; - OpenGLLogicalScalingFBO = 0; - OpenGLLogicalScalingColor = 0; - OpenGLLogicalScalingDepth = 0; - OpenGLLogicalScalingMultisampleFBO = 0; - OpenGLLogicalScalingMultisampleColor = 0; - OpenGLLogicalScalingMultisampleDepth = 0; + if (recreate_window) { + EndVidModeCreate(); /* rebuild the window if we can't resize it. */ } } From c4ffe41c95f5c40c2e2eaad452c9a1738b0da05f Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Wed, 22 May 2024 17:32:40 +0300 Subject: [PATCH 506/606] remove unnecarry assert. --- src/SDL12_compat.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index cf661e19b..710bea957 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -6107,7 +6107,6 @@ SetVideoModeImpl(int width, int height, int bpp, Uint32 flags12) } else if (VideoSurface12->surface20 && (VideoSurface12->surface20->format->format != appfmt)) { EndVidModeCreate(); /* rebuild the window if changing pixel format */ } else { - SDL_assert(VideoSurface12 != NULL); /* SDL 1.2 (infuriatingly!) destroys the window (and GL context!) on each resize in some cases, on various platforms. Try to match that. */ #ifdef __WINDOWS__ /* The windx5 driver _always_ destroyed the window, unconditionally, but the default (windib) did not, so match windib. From bec4bd04b5fdc19bc7bf6a7a417ae79978b0344a Mon Sep 17 00:00:00 2001 From: FoxMcCloud45 Date: Fri, 31 May 2024 18:47:26 +0200 Subject: [PATCH 507/606] quirks: Add SDL12COMPAT_COMPATIBILITY_AUDIOCVT=1 to "doukutsu.bin". doukustu.bin is the original executable of Cave Story's Linux port (1.01). Unlike the later v1.2 versions, the original version doesn't use audio correctly and thus requires this fix. The French version notably ships with this 1.01 executable instead of the v1.2 ones. --- src/SDL12_compat.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 710bea957..5480494a6 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1262,6 +1262,10 @@ static QuirkEntryType quirks[] = { {"dosbox_i686", "SDL12COMPAT_USE_KEYBOARD_LAYOUT", "0"}, {"dosbox_x86_64", "SDL12COMPAT_USE_KEYBOARD_LAYOUT", "0"}, + /* Cave Story's original doukutsu.bin misuses audio. */ + /* The later doukutsu_32bits and doukutsu_64bits work fine, however. */ + {"doukutsu.bin", "SDL12COMPAT_COMPATIBILITY_AUDIOCVT", "1"}, + /* Tucnak's 1.2 target wants to render and run its event loop from background threads, which upsets OpenGL. Force software renderer and x11. If you want Wayland, etc, use tuknak's existing SDL2 target. */ From 1d6dfdc33b86b71dfab4fe631e72fe7ee5c01ee1 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sun, 18 Aug 2024 01:40:24 +0300 Subject: [PATCH 508/606] updated SDL_endian.h from latest SDL2 --- include/SDL/SDL_endian.h | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/include/SDL/SDL_endian.h b/include/SDL/SDL_endian.h index d878e13ed..e5ea9cdc6 100644 --- a/include/SDL/SDL_endian.h +++ b/include/SDL/SDL_endian.h @@ -41,6 +41,15 @@ real SDL-1.2 available to you. */ #ifdef __linux__ #include #define SDL_BYTEORDER __BYTE_ORDER +#elif defined(__sun) && defined(__SVR4) /* Solaris */ +#include +#if defined(_LITTLE_ENDIAN) +#define SDL_BYTEORDER SDL_LIL_ENDIAN +#elif defined(_BIG_ENDIAN) +#define SDL_BYTEORDER SDL_BIG_ENDIAN +#else +#error Unsupported endianness +#endif #elif defined(__OpenBSD__) || defined(__DragonFly__) #include #define SDL_BYTEORDER BYTE_ORDER @@ -61,7 +70,7 @@ real SDL-1.2 available to you. */ defined(__m68k__) || defined(mc68000) || defined(_M_M68K) || \ (defined(__MIPS__) && defined(__MIPSEB__)) || \ defined(__ppc__) || defined(__POWERPC__) || defined(__powerpc__) || defined(__PPC__) || \ - defined(__sparc__) + defined(__sparc__) || defined(__sparc) #define SDL_BYTEORDER SDL_BIG_ENDIAN #else #define SDL_BYTEORDER SDL_LIL_ENDIAN From 6f0f603fb374f28a4680d4ab99d159d69877065e Mon Sep 17 00:00:00 2001 From: David Gow Date: Wed, 9 Oct 2024 22:38:24 +0800 Subject: [PATCH 509/606] quirks: Closure needs OpenGL scaling disabled (Fix #342) Closure uses Cg, and also generally doesn't play nicely with OpenGL scaling, resulting in a black screen. Disabling OpenGL scaling lets the game work properly, so add a quirk to do this by default. Tested against the Humble Indie Bundle 7 build (Closure-Linux-1.1-2012-12-28.sh), and it seems to work fine. --- src/SDL12_compat.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 5480494a6..d72a9c6d5 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1257,6 +1257,10 @@ static QuirkEntryType quirks[] = { /* Braid uses Cg, which uses glXGetProcAddress(). */ {"braid", "SDL12COMPAT_OPENGL_SCALING", "0"}, + /* Closure uses Cg, and doesn't render anything with OpenGL scaling. */ + {"Closure.bin.x86", "SDL12COMPAT_OPENGL_SCALING", "0"}, + {"Closure.bin.x86_64", "SDL12COMPAT_OPENGL_SCALING", "0"}, + /* GOG's DOSBox builds have architecture-specific filenames. */ {"dosbox", "SDL12COMPAT_USE_KEYBOARD_LAYOUT", "0"}, {"dosbox_i686", "SDL12COMPAT_USE_KEYBOARD_LAYOUT", "0"}, From 75ac6c6e39cf897d30958c603e004bc0d1cbfa63 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sun, 15 Dec 2024 00:37:02 +0300 Subject: [PATCH 510/606] updated SDL_platform.h from latest SDL2. --- include/SDL/SDL_platform.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/SDL/SDL_platform.h b/include/SDL/SDL_platform.h index 9b27621e0..9e667b8e4 100644 --- a/include/SDL/SDL_platform.h +++ b/include/SDL/SDL_platform.h @@ -75,7 +75,13 @@ requirement is dropped too. Send patches. :) */ #if defined(__APPLE__) /* lets us know what version of Mac OS X we're compiling on */ #include +#ifndef __has_extension /* Older compilers don't support this */ +#define __has_extension(x) 0 #include +#undef __has_extension +#else +#include +#endif /* Fix building with older SDKs that don't define these See this for more information: From 082a98600bbe11b68581edc2bf2cdd3dfa7cfc82 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 3 Feb 2025 23:15:44 -0500 Subject: [PATCH 511/606] quirks: Force Loki's Unreal Tournament build to sync to vblank. Reference https://github.com/libsdl-org/sdl2-compat/issues/283 --- src/SDL12_compat.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index d72a9c6d5..6b87d59e6 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1318,7 +1318,10 @@ static QuirkEntryType quirks[] = { {"grafx2", "SDL12COMPAT_ALLOW_SYSWM", "0"}, /* The 32-bit Steam build only of Multiwinia Quits but doesn't re-Init */ - {"multiwinia.bin.x86", "SDL12COMPAT_NO_QUIT_VIDEO", "1"} + {"multiwinia.bin.x86", "SDL12COMPAT_NO_QUIT_VIDEO", "1"}, + + /* Loki Unreal Tournament '99 runs at hyperspeed if the framerate is too high. Force it to vsync. You should use the newer OldUnreal binaries with SDL2 instead! */ + {"ut-bin", "SDL12COMPAT_SYNC_TO_VBLANK", "1"} #else /* TODO: Add any quirks needed for this system. */ From c36ad5d94bdd760b0116c18d7f65417049d4c23c Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 6 Feb 2025 12:34:01 -0500 Subject: [PATCH 512/606] Merged changes from sdl2-compat: don't call into the newer SDL during startup. --- src/SDL12_compat.c | 272 ++++++++++++++++++++++++++++++++++------ src/SDL12_compat_objc.m | 13 ++ 2 files changed, 249 insertions(+), 36 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 6b87d59e6..51e538035 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1069,6 +1069,45 @@ SDL20_atoi(const char *str) return SDL20_strtol(str, NULL, 10); } +/* you can use SDL20_atoi once we're past startup. */ +static int +SDL12COMPAT_atoi(const char *str) +{ + int retval = 0; + int multiplier = 1; + int signmult = 1; + const char *ptr; + + while (*str == ' ') { + str++; + } + + if (*str == '-') { + signmult = -1; + str++; + while (*str == ' ') { + str++; + } + } + + ptr = str; + while (SDL_TRUE) { + if ((*ptr < '0') || (*ptr > '9')) { + break; + } + ptr++; + } + ptr--; + + while (ptr != str) { + retval += ((int) (*ptr - '0')) * multiplier; + multiplier *= 10; + ptr--; + } + + return (retval + (((int) (*ptr - '0')) * multiplier)) * signmult; +} + static char * SDL12COMPAT_stpcpy(char *dst, const char *src) { @@ -1103,6 +1142,78 @@ SDL12COMPAT_itoa(char *dst, int val) } while (ptr > dst); } +/* you can use SDL20_strlen once we're past startup. */ +static int SDL12COMPAT_strlen(const char *str) +{ + int retval = 0; + while (str[retval]) { + retval++; + } + return retval; +} + +/* you can use SDL20_strcmp once we're past startup. */ +static SDL_bool SDL12COMPAT_strequal(const char *a, const char *b) +{ + while (SDL_TRUE) { + const char cha = *a; + if (cha != *b) { + return SDL_FALSE; + } else if (!cha) { + break; + } + a++; + b++; + } + return SDL_TRUE; +} + +/* log a string using platform-specific code for before SDL2 is fully available. */ +static void SDL12COMPAT_LogAtStartup(const char *str) +{ + #ifdef _WIN32 + OutputDebugStringA(str); + #elif defined(__APPLE__) + extern void SDL12COMPAT_NSLog(const char *prefix, const char *text); + SDL12COMPAT_NSLog(NULL, str); + #else + fputs(str, stderr); + fputs("\n", stderr); + #endif +} + +/* this talks right to the OS environment table. Don't use SDL20_setenv at startup. */ +static void SDL12COMPAT_SetEnvAtStartup(const char *name, const char *value) +{ + #ifdef _WIN32 + SetEnvironmentVariableA(name, value); + #else /* we might need other platforms, or a simple `return;` for platforms without an environment table. */ + if (value) { + setenv(name, value, 1); + } else { + unsetenv(name); + } + #endif +} + +/* this talks right to the OS environment table. Don't use SDL20_getenv at startup. */ +static const char *SDL12COMPAT_GetEnvAtStartup(const char *name) +{ + #ifdef _WIN32 + static char buf[256]; /* overflows will just report as environment variable being unset. But most of our environment vars don't come through here. */ + const DWORD rc = GetEnvironmentVariableA(name, buf, (DWORD) sizeof (buf)); + return ((rc != 0) && (rc < sizeof (buf))) ? buf : NULL; + #else /* we might need other platforms, or a simple `return NULL;` for platforms without an environment table. */ + return getenv(name); + #endif +} + +/* this can't call into SDL20_getenv because things aren't set up yet, so try for platform-specific getenv checks. */ +static SDL_bool SDL12COMPAT_CheckDebugLogging(void) +{ + const char *value = SDL12COMPAT_GetEnvAtStartup("SDL12COMPAT_DEBUG_LOGGING"); + return ((value != NULL) && SDL12COMPAT_strequal(value, "1")) ? SDL_TRUE : SDL_FALSE; +} /* Obviously we can't use SDL_LoadObject() to load SDL2. :) */ static char loaderror[256]; @@ -1428,6 +1539,7 @@ SDL12Compat_GetHintInt(const char *name, int default_value) return SDL20_atoi(val); } +/* DO NOT USE SDL2 FUNCTIONS IN HERE! */ static void SDL12Compat_ApplyQuirks(SDL_bool force_x11) { @@ -1435,21 +1547,37 @@ SDL12Compat_ApplyQuirks(SDL_bool force_x11) int i; if (WantDebugLogging) { - SDL20_Log("This app appears to be named '%s'", exe_name); + const char *lead = "sdl12-compat: This app appears to be named:"; + char msg[256]; + if ((SDL12COMPAT_strlen(lead) + SDL12COMPAT_strlen(exe_name) + 2) <= (int) (sizeof (msg))) { + char *p = msg; + p = SDL12COMPAT_stpcpy(p, lead); + p = SDL12COMPAT_stpcpy(p, " "); + p = SDL12COMPAT_stpcpy(p, exe_name); + SDL12COMPAT_LogAtStartup(msg); + } else { + SDL12COMPAT_LogAtStartup(lead); + SDL12COMPAT_LogAtStartup(exe_name); + } } #ifdef __linux__ if (force_x11) { - const char *videodriver_env = SDL20_getenv("SDL_VIDEODRIVER"); - if (videodriver_env && (SDL20_strcmp(videodriver_env, "x11") != 0)) { + const char *videodriver_env = SDL12COMPAT_GetEnvAtStartup("SDL_VIDEODRIVER"); + if (videodriver_env && !SDL12COMPAT_strequal(videodriver_env, "x11")) { if (WantDebugLogging) { - SDL20_Log("This app looks like it requires X11, but the SDL_VIDEODRIVER environment variable is set to \"%s\". If you have issues, try setting SDL_VIDEODRIVER=x11", videodriver_env); + SDL12COMPAT_LogAtStartup("sdl12-compat: This app looks like it requires X11, but the SDL_VIDEODRIVER environment variable is currently set to:"); + SDL12COMPAT_LogAtStartup(""); + SDL12COMPAT_LogAtStartup(videodriver_env); + SDL12COMPAT_LogAtStartup(""); + SDL12COMPAT_LogAtStartup("If you have issues, try setting SDL_VIDEODRIVER=x11"); + } } else { if (WantDebugLogging) { - SDL20_Log("sdl12-compat: We are forcing this app to use X11, because it probably talks to an X server directly, outside of SDL. If possible, this app should be fixed, to be compatible with Wayland, etc."); + SDL12COMPAT_LogAtStartup("sdl12-compat: We are forcing this app to use X11, because it probably talks to an X server directly, outside of SDL. If possible, this app should be fixed, to be compatible with Wayland, etc."); } - SDL20_setenv("SDL_VIDEODRIVER", "x11", 1); + SDL12COMPAT_SetEnvAtStartup("SDL_VIDEODRIVER", "x11"); } } #endif @@ -1457,23 +1585,58 @@ SDL12Compat_ApplyQuirks(SDL_bool force_x11) if (*exe_name == '\0') { return; } + for (i = 0; i < (int) SDL_arraysize(quirks); i++) { - if (!SDL20_strcmp(exe_name, quirks[i].exe_name)) { - if (!SDL20_getenv(quirks[i].hint_name)) { + if (SDL12COMPAT_strequal(exe_name, quirks[i].exe_name)) { + const char *var = SDL12COMPAT_GetEnvAtStartup(quirks[i].hint_name); + if (!var) { if (WantDebugLogging) { - SDL20_Log("Applying compatibility quirk %s=\"%s\" for \"%s\"", quirks[i].hint_name, quirks[i].hint_value, exe_name); + char msg[256]; + char *p = msg; + p = SDL12COMPAT_stpcpy(p, "sdl12-compat: Applying compatibility quirk "); + p = SDL12COMPAT_stpcpy(p, quirks[i].hint_name); + p = SDL12COMPAT_stpcpy(p, "=\""); + p = SDL12COMPAT_stpcpy(p, quirks[i].hint_value); + p = SDL12COMPAT_stpcpy(p, "\"."); + SDL12COMPAT_LogAtStartup(msg); } - SDL20_setenv(quirks[i].hint_name, quirks[i].hint_value, 1); + SDL12COMPAT_SetEnvAtStartup(quirks[i].hint_name, quirks[i].hint_value); } else { if (WantDebugLogging) { - SDL20_Log("Not applying compatibility quirk %s=\"%s\" for \"%s\" due to environment variable override (\"%s\")\n", - quirks[i].hint_name, quirks[i].hint_value, exe_name, SDL20_getenv(quirks[i].hint_name)); + char msg[256]; + char varbuf[32]; + char *p = msg; + int j; + + /* copy the start of untrusted string var to a small array to prevent buffer overflows */ + for (j = 0; j < ((int) SDL_arraysize(varbuf)); j++) { + varbuf[j] = var[j]; + if (var[j] == 0) { + break; + } + } + + if (j == SDL_arraysize(varbuf)) { /* truncate and terminate the string if necessary. */ + SDL12COMPAT_stpcpy(varbuf + (SDL_arraysize(varbuf) - 6), "[...]"); + } + + p = SDL12COMPAT_stpcpy(p, "sdl12-compat: Not applying compatibility quirk "); + p = SDL12COMPAT_stpcpy(p, quirks[i].hint_name); + p = SDL12COMPAT_stpcpy(p, "=\""); + p = SDL12COMPAT_stpcpy(p, quirks[i].hint_value); + p = SDL12COMPAT_stpcpy(p, "\" due to environment variable override (\""); + p = SDL12COMPAT_stpcpy(p, varbuf); + p = SDL12COMPAT_stpcpy(p, "\")."); + SDL12COMPAT_LogAtStartup(msg); } } } } } +/* DO NOT CALL THINGS THAT USE SDL ALLOCATORS HERE. It runs before main(), so app-supplied allocators are not set at this point. + This means no SDL_Log, no hint subsystem, nothing that might call SDL_SetError! In fact, favor code in this file, using + platform-specific #ifdefs, to calling into SDL2 at all, if you can help it. */ static int LoadSDL20(void) { @@ -1497,51 +1660,88 @@ LoadSDL20(void) } #endif + WantDebugLogging = SDL12COMPAT_CheckDebugLogging(); + okay = LoadSDL20Library(); if (!okay) { - SDL12COMPAT_stpcpy(loaderror, "Failed loading SDL2 library."); + SDL12COMPAT_stpcpy(loaderror, "sdl12-compat: Failed loading SDL2 library."); } else { #define SDL20_SYM(rc,fn,params,args,ret) SDL20_##fn = (SDL20_##fn##_t) LoadSDL20Symbol("SDL_" #fn, &okay); #include "SDL20_syms.h" if (okay) { + char sdl2verstr[16]; + char sdl2reqverstr[16]; + char sdl12compatverstr[16]; SDL_version v; + SDL_version reqv; + char *p; + SDL20_GetVersion(&v); + + reqv.major = (SDL20_REQUIRED_VER / 1000); + reqv.minor = ((SDL20_REQUIRED_VER % 1000) / 100); + reqv.patch = (SDL20_REQUIRED_VER % 100); + + #define SETVERSTR(str, major, minor, micro) { \ + char value[16]; \ + p = str; \ + SDL12COMPAT_itoa(value, major); p = SDL12COMPAT_stpcpy(p, value); *p++ = '.'; \ + SDL12COMPAT_itoa(value, minor); p = SDL12COMPAT_stpcpy(p, value); *p++ = '.'; \ + SDL12COMPAT_itoa(value, micro); p = SDL12COMPAT_stpcpy(p, value); \ + } + + SETVERSTR(sdl2verstr, v.major, v.minor, v.patch); + SETVERSTR(sdl2reqverstr, reqv.major, reqv.minor, reqv.patch); + SETVERSTR(sdl12compatverstr, 1, 2, SDL12_COMPAT_VERSION); + + #undef SETVERSTR + LinkedSDL2VersionInt = SDL_VERSIONNUM(v.major, v.minor, v.patch); okay = (LinkedSDL2VersionInt >= SDL20_REQUIRED_VER); if (!okay) { - char value[12]; - char *p = SDL12COMPAT_stpcpy(loaderror, "SDL2 "); - - SDL12COMPAT_itoa(value, v.major); - p = SDL12COMPAT_stpcpy(p, value); *p++ = '.'; - SDL12COMPAT_itoa(value, v.minor); - p = SDL12COMPAT_stpcpy(p, value); *p++ = '.'; - SDL12COMPAT_itoa(value, v.patch); - p = SDL12COMPAT_stpcpy(p, value); - - SDL12COMPAT_stpcpy(p, " library is too old."); + p = loaderror; + p = SDL12COMPAT_stpcpy(p, "sdl12-compat "); + p = SDL12COMPAT_stpcpy(p, sdl12compatverstr); + p = SDL12COMPAT_stpcpy(p, ": SDL2 library is too old (have "); + p = SDL12COMPAT_stpcpy(p, sdl2verstr); + p = SDL12COMPAT_stpcpy(p, ", but need at least "); + p = SDL12COMPAT_stpcpy(p, sdl2reqverstr); + p = SDL12COMPAT_stpcpy(p, ")."); } else { - WantDebugLogging = SDL12Compat_GetHintBoolean("SDL12COMPAT_DEBUG_LOGGING", SDL_FALSE); if (WantDebugLogging) { + char debugmsg[128]; /* can't use SDL log or malloc, just write to a stack buffer and do a simple platform-specific logging. */ + + p = debugmsg; + p = SDL12COMPAT_stpcpy(p, "sdl12-compat "); + p = SDL12COMPAT_stpcpy(p, sdl12compatverstr); + p = SDL12COMPAT_stpcpy(p, ", "); + #if defined(__DATE__) && defined(__TIME__) - SDL20_Log("sdl12-compat 1.2.%d, built on " __DATE__ " at " __TIME__ ", talking to SDL2 %d.%d.%d", SDL12_COMPAT_VERSION, v.major, v.minor, v.patch); - #else - SDL20_Log("sdl12-compat 1.2.%d, talking to SDL2 %d.%d.%d", SDL12_COMPAT_VERSION, v.major, v.minor, v.patch); + p = SDL12COMPAT_stpcpy(p, "built on " __DATE__ " at " __TIME__ ", "); #endif + + p = SDL12COMPAT_stpcpy(p, "talking to SDL2 "); + p = SDL12COMPAT_stpcpy(p, sdl2verstr); + + SDL12COMPAT_LogAtStartup(debugmsg); } + SDL12Compat_ApplyQuirks(force_x11); /* Apply and maybe print a list of any enabled quirks. */ #ifdef __linux__ { - const char *viddrv = SDL20_getenv("SDL_VIDEODRIVER"); - if (viddrv && (SDL20_strcmp(viddrv, "x11") == 0) && SDL12Compat_GetHintBoolean("SDL12COMPAT_FORCE_XINITTHREADS", SDL_TRUE)) { - void *lib = dlopen("libX11.so.6", RTLD_GLOBAL|RTLD_NOW); - if (lib) { - int (*pXInitThreads)(void) = (int(*)(void)) dlsym(lib, "XInitThreads"); - if (pXInitThreads) { - pXInitThreads(); + const char *envvar = SDL12COMPAT_GetEnvAtStartup("SDL_VIDEODRIVER"); + if (envvar && SDL12COMPAT_strequal(envvar, "x11")) { + envvar = SDL12COMPAT_GetEnvAtStartup("SDL12COMPAT_FORCE_XINITTHREADS"); + if (envvar && (SDL12COMPAT_atoi(envvar) != 0)) { + void *lib = dlopen("libX11.so.6", RTLD_GLOBAL|RTLD_NOW); + if (lib) { + int (*pXInitThreads)(void) = (int(*)(void)) dlsym(lib, "XInitThreads"); + if (pXInitThreads) { + pXInitThreads(); + } + /* leave the library open, so the XInitThreads sticks. */ } - /* leave the library open, so the XInitThreads sticks. */ } } } diff --git a/src/SDL12_compat_objc.m b/src/SDL12_compat_objc.m index 25eeed757..31f0ec8f2 100644 --- a/src/SDL12_compat_objc.m +++ b/src/SDL12_compat_objc.m @@ -63,6 +63,19 @@ SDL12_PRIVATE void error_dialog(const char *errorMsg) alert.informativeText = [NSString stringWithCString:errorMsg encoding:NSASCIIStringEncoding]; [alert runModal]; } + +SDL12_PRIVATE void SDL12COMPAT_NSLog(const char *prefix, const char *text) +{ + @autoreleasepool { + NSString *nsText = [NSString stringWithUTF8String:text]; + if (prefix && *prefix) { + NSString *nsPrefix = [NSString stringWithUTF8String:prefix]; + NSLog(@"%@%@", nsPrefix, nsText); + } else { + NSLog(@"%@", nsText); + } + } +} #endif /* vi: set ts=4 sw=4 expandtab: */ From e3527ec8e9c1171e90fc190f66715f6ee8ae2c32 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Thu, 6 Feb 2025 23:11:40 +0300 Subject: [PATCH 513/606] fix os/2 watcom builds using ow1.9 --- src/SDL12_compat.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 51e538035..9f16a96af 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1187,6 +1187,8 @@ static void SDL12COMPAT_SetEnvAtStartup(const char *name, const char *value) { #ifdef _WIN32 SetEnvironmentVariableA(name, value); + #elif defined (__WATCOMC__) + setenv(name, value, 1); /* OW19 has no unsetenv(). NULL newvalue passed to setenv() behaves as unsetenv(). */ #else /* we might need other platforms, or a simple `return;` for platforms without an environment table. */ if (value) { setenv(name, value, 1); From 9f3a01c14126a9eabd11901f645747f8e1853c45 Mon Sep 17 00:00:00 2001 From: diekleinekuh Date: Fri, 7 Feb 2025 12:12:03 +0100 Subject: [PATCH 514/606] replace CMAKE_SOURCE/BINARY_DIR with CMAKE_CURRENT_SOURC/UBINARY_DIR --- CMakeLists.txt | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 89e5c562a..fe065bb5d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -233,7 +233,7 @@ if(SDL12TESTS) endif() foreach(fname "icon.bmp" "moose.dat" "picture.xbm" "sail.bmp" "sample.bmp" "sample.wav" "utf8.txt") - file(COPY "${CMAKE_SOURCE_DIR}/test/${fname}" DESTINATION "${CMAKE_BINARY_DIR}") + file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/test/${fname}" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}") endforeach(fname) endif() @@ -282,12 +282,12 @@ if(SDL12DEVEL) set(ENABLE_SHARED_FALSE "#") configure_file(sdl12_compat.pc.in sdl12_compat.pc @ONLY) - install(FILES ${CMAKE_BINARY_DIR}/sdl12_compat.pc + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/sdl12_compat.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig ) - configure_file("${CMAKE_SOURCE_DIR}/sdl-config.in" "${CMAKE_BINARY_DIR}/sdl-config" @ONLY) - install(PROGRAMS "${CMAKE_BINARY_DIR}/sdl-config" DESTINATION bin) + configure_file("${CMAKE_CURRENT_SOURCE_DIR}/sdl-config.in" "${CMAKE_CURRENT_BINARY_DIR}/sdl-config" @ONLY) + install(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/sdl-config" DESTINATION bin) endif() set(SOEXT ${CMAKE_SHARED_LIBRARY_SUFFIX}) @@ -296,11 +296,11 @@ if(SDL12DEVEL) install(CODE " execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink \"lib${SONAME}${SOPOSTFIX}${SOEXT}\" \"libSDL${SOPOSTFIX}${SOEXT}\" - WORKING_DIRECTORY \"${CMAKE_BINARY_DIR}\")") - install(FILES ${CMAKE_BINARY_DIR}/libSDL${SOPOSTFIX}${SOEXT} DESTINATION "${CMAKE_INSTALL_LIBDIR}") + WORKING_DIRECTORY \"${CMAKE_CURRENT_BINARY_DIR}\")") + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libSDL${SOPOSTFIX}${SOEXT} DESTINATION "${CMAKE_INSTALL_LIBDIR}") endif() - install(FILES "${CMAKE_SOURCE_DIR}/sdl.m4" DESTINATION "${CMAKE_INSTALL_FULL_DATAROOTDIR}/aclocal") + install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/sdl.m4" DESTINATION "${CMAKE_INSTALL_FULL_DATAROOTDIR}/aclocal") endif() if(STATICDEVEL AND SDL12DEVEL) From 283ecc78aa78cef409ba2a189feafe86e884496a Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Mon, 10 Feb 2025 23:37:40 +0300 Subject: [PATCH 515/606] SDL2Compat_strlen: hack to prevent gcc optimizing the code into strlen making retval volatile prevents gcc optimizing the code into strlen and defeating the purpose of the procedure. Reference issue: https://github.com/libsdl-org/sdl2-compat/issues/340 --- src/SDL12_compat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 9f16a96af..78936dd91 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1145,7 +1145,7 @@ SDL12COMPAT_itoa(char *dst, int val) /* you can use SDL20_strlen once we're past startup. */ static int SDL12COMPAT_strlen(const char *str) { - int retval = 0; + volatile int retval = 0; /* volatile prevents gcc from optimizing this into strlen() */ while (str[retval]) { retval++; } From 35a63c6d1445c51f042dd3dd3f960be19c18b244 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Thu, 13 Feb 2025 10:11:04 +0300 Subject: [PATCH 516/606] updated dr_mp3 from mainstream. --- src/dr_mp3.h | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/src/dr_mp3.h b/src/dr_mp3.h index 7dd8fa474..f07dcf5e7 100644 --- a/src/dr_mp3.h +++ b/src/dr_mp3.h @@ -1,6 +1,6 @@ /* MP3 audio decoder. Choice of public domain or MIT-0. See license statements at the end of this file. -dr_mp3 - v0.6.38 - 2023-11-02 +dr_mp3 - v0.6.40 - 2024-12-17 David Reid - mackron@gmail.com @@ -33,7 +33,7 @@ Support for loading a file from a `wchar_t` string has been added via the `drmp3 */ /* -Introducation +Introduction ============= dr_mp3 is a single file library. To use it, do something like the following in one .c file. @@ -101,7 +101,7 @@ extern "C" { #define DRMP3_VERSION_MAJOR 0 #define DRMP3_VERSION_MINOR 6 -#define DRMP3_VERSION_REVISION 38 +#define DRMP3_VERSION_REVISION 40 #define DRMP3_VERSION_STRING DRMP3_XSTRINGIFY(DRMP3_VERSION_MAJOR) "." DRMP3_XSTRINGIFY(DRMP3_VERSION_MINOR) "." DRMP3_XSTRINGIFY(DRMP3_VERSION_REVISION) #include /* For size_t. */ @@ -130,7 +130,7 @@ typedef unsigned int drmp3_uint32; #pragma GCC diagnostic pop #endif #endif -#if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__)) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(_M_ARM64) || defined(__powerpc64__) +#if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__)) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(_M_ARM64) || defined(_M_ARM64EC) || defined(__powerpc64__) typedef drmp3_uint64 drmp3_uintptr; #else typedef drmp3_uint32 drmp3_uintptr; @@ -621,7 +621,7 @@ DRMP3_API const char* drmp3_version_string(void) #if !defined(DR_MP3_NO_SIMD) -#if !defined(DR_MP3_ONLY_SIMD) && (defined(_M_X64) || defined(__x86_64__) || defined(__aarch64__) || defined(_M_ARM64)) +#if !defined(DR_MP3_ONLY_SIMD) && (defined(_M_X64) || defined(__x86_64__) || defined(__aarch64__) || defined(_M_ARM64) || defined(_M_ARM64EC)) /* x64 always have SSE2, arm64 always have neon, no need for generic code */ #define DR_MP3_ONLY_SIMD #endif @@ -697,7 +697,7 @@ static int drmp3_have_simd(void) return g_have_simd - 1; #endif } -#elif defined(__ARM_NEON) || defined(__aarch64__) || defined(_M_ARM64) +#elif defined(__ARM_NEON) || defined(__aarch64__) || defined(_M_ARM64) || defined(_M_ARM64EC) #include #define DRMP3_HAVE_SSE 0 #define DRMP3_HAVE_SIMD 1 @@ -730,7 +730,7 @@ static int drmp3_have_simd(void) #endif -#if defined(__ARM_ARCH) && (__ARM_ARCH >= 6) && !defined(__aarch64__) && !defined(_M_ARM64) && !defined(__ARM_ARCH_6M__) +#if defined(__ARM_ARCH) && (__ARM_ARCH >= 6) && !defined(__aarch64__) && !defined(_M_ARM64) && !defined(_M_ARM64EC) && !defined(__ARM_ARCH_6M__) #define DRMP3_HAVE_ARMV6 1 static __inline__ __attribute__((always_inline)) drmp3_int32 drmp3_clip_int16_arm(drmp3_int32 a) { @@ -2002,8 +2002,8 @@ static drmp3_int16 drmp3d_scale_pcm(float sample) s32 -= (s32 < 0); s = (drmp3_int16)drmp3_clip_int16_arm(s32); #else - if (sample >= 32766.5) return (drmp3_int16) 32767; - if (sample <= -32767.5) return (drmp3_int16)-32768; + if (sample >= 32766.5f) return (drmp3_int16) 32767; + if (sample <= -32767.5f) return (drmp3_int16)-32768; s = (drmp3_int16)(sample + .5f); s -= (s < 0); /* away from zero, to be compliant */ #endif @@ -2422,9 +2422,9 @@ DRMP3_API void drmp3dec_f32_to_s16(const float *in, drmp3_int16 *out, size_t num for(; i < num_samples; i++) { float sample = in[i] * 32768.0f; - if (sample >= 32766.5) + if (sample >= 32766.5f) out[i] = (drmp3_int16) 32767; - else if (sample <= -32767.5) + else if (sample <= -32767.5f) out[i] = (drmp3_int16)-32768; else { @@ -3582,7 +3582,7 @@ DRMP3_API void drmp3_uninit(drmp3* pMP3) if (pMP3 == NULL) { return; } - + #ifndef DR_MP3_NO_STDIO if (pMP3->onRead == drmp3__on_read_stdio) { FILE* pFile = (FILE*)pMP3->pUserData; @@ -3973,7 +3973,7 @@ DRMP3_API drmp3_bool32 drmp3_get_mp3_and_pcm_frame_count(drmp3* pMP3, drmp3_uint /* We'll need to seek back to where we were, so grab the PCM frame we're currently sitting on so we can restore later. */ currentPCMFrame = pMP3->currentPCMFrame; - + if (!drmp3_seek_to_start_of_stream(pMP3)) { return DRMP3_FALSE; } @@ -4071,7 +4071,7 @@ DRMP3_API drmp3_bool32 drmp3_calculate_seek_points(drmp3* pMP3, drmp3_uint32* pS /* We'll need to seek back to the current sample after calculating the seekpoints so we need to go ahead and grab the current location at the top. */ currentPCMFrame = pMP3->currentPCMFrame; - + /* We never do more than the total number of MP3 frames and we limit it to 32-bits. */ if (!drmp3_get_mp3_and_pcm_frame_count(pMP3, &totalMP3FrameCount, &totalPCMFrameCount)) { return DRMP3_FALSE; @@ -4522,6 +4522,12 @@ counts rather than sample counts. /* REVISION HISTORY ================ +v0.6.40 - 2024-12-17 + - Improve detection of ARM64EC + +v0.6.39 - 2024-02-27 + - Fix a Wdouble-promotion warning. + v0.6.38 - 2023-11-02 - Fix build for ARMv6-M. From fc8a53c98755e22001402bf5258120ab3ece2820 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sun, 16 Feb 2025 13:11:22 -0500 Subject: [PATCH 517/606] README.md: tell people to use SDL3 directly now, instead of SDL2. --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 443574245..43f325eae 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ and 2D framebuffer across multiple platforms. This code is a compatibility layer; it provides a binary and source compatible API for programs written against SDL 1.2, but it uses SDL 2.0 -behind the scenes. If you are writing new code, please target SDL 2.0 +behind the scenes. If you are writing new code, please target SDL 3.0 directly and do not use this layer. If you absolutely must have the real SDL 1.2 ("SDL 1.2 Classic"), please use @@ -136,7 +136,7 @@ sdl12-compat has a number of configuration options which can be used to work around issues with individual applications, or to better fit your system or preferences. -These options are all specified as environment variables, and can be set by +These options argoe all specified as environment variables, and can be set by running your application with them set on the command-line, for example: ``` SDL12COMPAT_HIGHDPI=1 SDL12COMPAT_OPENGL_SCALING=0 %command% From a1527613760a29e0cbefa74a9c26a8ddcb3020aa Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sun, 16 Feb 2025 13:13:48 -0500 Subject: [PATCH 518/606] README.md: SDL2 versions might not be "2.0.x" anymore. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 43f325eae..928c727d6 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ You'll need to use CMake to build sdl12-compat. Download at Please refer to the [CMake documentation](https://cmake.org/documentation/) for complete details, as platform and build tool details vary. -You'll need a copy of SDL 2.0.x to build sdl12-compat, because we need the +You'll need a copy of SDL2 to build sdl12-compat, because we need the SDL2 headers. You can build this from source or install from a package manager. Windows and Mac users can download prebuilt binaries from [SDL's download page](https://libsdl.org/download-2.0.php); make sure you From a7d7c4cbc1ea72a4214664f1e4d934e3cce6127c Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sun, 16 Feb 2025 13:17:35 -0500 Subject: [PATCH 519/606] README.md: fixed typo. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 928c727d6..58cd6f8d1 100644 --- a/README.md +++ b/README.md @@ -136,7 +136,7 @@ sdl12-compat has a number of configuration options which can be used to work around issues with individual applications, or to better fit your system or preferences. -These options argoe all specified as environment variables, and can be set by +These options are all specified as environment variables, and can be set by running your application with them set on the command-line, for example: ``` SDL12COMPAT_HIGHDPI=1 SDL12COMPAT_OPENGL_SCALING=0 %command% From 33c743a53dc4c3178027777ba4f6b995277e6bc2 Mon Sep 17 00:00:00 2001 From: Humberto Dias Date: Mon, 17 Feb 2025 11:00:05 -0300 Subject: [PATCH 520/606] CI: Build for arm64 (#346) --- .github/workflows/main.yml | 16 +++++++++------- .github/workflows/watcom.yml | 4 ++-- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 2c1267e31..0df2ce16e 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -10,18 +10,20 @@ jobs: matrix: platform: - { name: Windows, os: windows-latest } - - { name: Linux, os: ubuntu-latest, flags: -GNinja } - - { name: MacOS, os: macos-latest } + - { name: Linux-x86_64, os: ubuntu-24.04, flags: -GNinja } + - { name: Linux-arm64, os: ubuntu-24.04-arm, flags: -GNinja } + - { name: MacOS-arm, os: macos-latest } + - { name: MacOS-intel, os: macos-13 } steps: - name: Setup Linux dependencies - if: runner.os == 'Linux' + if: startsWith(runner.os, 'Linux') run: | - sudo apt-get update - sudo apt-get install cmake ninja-build libgl1-mesa-dev libglu1-mesa-dev + sudo apt update -q + sudo apt install -y cmake ninja-build libgl1-mesa-dev libglu1-mesa-dev - name: Get sdl12-compat sources - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Get SDL2 headers - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: repository: libsdl-org/SDL ref: SDL2 diff --git a/.github/workflows/watcom.yml b/.github/workflows/watcom.yml index 0c9e6c978..81b9e2283 100644 --- a/.github/workflows/watcom.yml +++ b/.github/workflows/watcom.yml @@ -16,9 +16,9 @@ jobs: steps: - uses: open-watcom/setup-watcom@v0 - name: Get sdl12-compat sources - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Get SDL2 headers - uses: actions/checkout@v2 + uses: actions/checkout@v4 with: repository: libsdl-org/SDL ref: SDL2 From cf3e5bd8c53eaf1297e9f079336ec783016b182c Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Tue, 4 Mar 2025 14:05:50 +0300 Subject: [PATCH 521/606] cmake: set maximum policy to 3.10 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index fe065bb5d..57d9052e0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ # you can define SDL2_INCLUDE_DIR on the cmdline. For example: # cmake -DSDL2_INCLUDE_DIR=/opt/SDL2/include/SDL2 [other stuff] -cmake_minimum_required(VERSION 3.0.0...3.5) +cmake_minimum_required(VERSION 3.0.0...3.10) project(sdl12_compat VERSION 1.2.69 LANGUAGES C) From 60ba97c41e53dfa34f50eb4741c3a758739623d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=2E=20Neusch=C3=A4fer?= Date: Wed, 5 Mar 2025 13:30:17 +0100 Subject: [PATCH 522/606] video: Reflect SDL12_RESIZABLE in SDL12_Surface->flags Code depends on being able to see the RESIZABLE flag in video surfaces. For example, the Perl module SDLx::App will throw an error if it tries to resize a surface but doesn't find SDL_RESIZABLE in its flags: https://metacpan.org/release/FROGGS/SDL-2.548/source/lib/SDLx/App.pm#L143 To improve compatibility with such code, copy the flag to the VideoSurface12 created in SDL_SetVideoMode. --- src/SDL12_compat.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 78936dd91..84a422c7b 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -6469,6 +6469,12 @@ SetVideoModeImpl(int width, int height, int bpp, Uint32 flags12) VideoSurface12->flags &= ~SDL12_FULLSCREEN; } + if (flags12 & SDL12_RESIZABLE) { + VideoSurface12->flags |= SDL12_RESIZABLE; + } else { + VideoSurface12->flags &= ~SDL12_RESIZABLE; + } + if (flags12 & SDL12_OPENGL) { SDL_assert(!VideoTexture20); /* either a new window or we destroyed all this */ SDL_assert(!VideoRenderer20); From 990ce7bd9a19720b3481154edbcd31b42318457f Mon Sep 17 00:00:00 2001 From: lif <> Date: Mon, 10 Mar 2025 03:17:34 -0700 Subject: [PATCH 523/606] SDL_stdinc.h: Fix apparent copy/paste error SDL_strcasecmp, rather than SDL_strncasecmp, being defined as _strnicmp. --- include/SDL/SDL_stdinc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/SDL/SDL_stdinc.h b/include/SDL/SDL_stdinc.h index e7b3b007c..dd4c25c81 100644 --- a/include/SDL/SDL_stdinc.h +++ b/include/SDL/SDL_stdinc.h @@ -340,7 +340,7 @@ extern DECLSPEC int SDLCALL SDL_strcasecmp(const char *str1, const char *str2); #ifdef HAVE_STRNCASECMP #define SDL_strncasecmp strncasecmp #elif defined(HAVE__STRNICMP) -#define SDL_strcasecmp _strnicmp +#define SDL_strncasecmp _strnicmp #else extern DECLSPEC int SDLCALL SDL_strncasecmp(const char *str1, const char *str2, size_t maxlen); #endif From c6b4b032cabd9a417ca76a9bcfa660bee5878364 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Thu, 27 Mar 2025 14:50:10 +0300 Subject: [PATCH 524/606] CI: update, and run MSVC workflow for both x86 and x64. TODO: Maybe support MinGW (both GCC- and Clang-based) workflows? --- .github/workflows/main.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 0df2ce16e..9cf0d9693 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -9,11 +9,12 @@ jobs: strategy: matrix: platform: - - { name: Windows, os: windows-latest } + - { name: Windows-MSVC-x86, os: windows-latest, flags: -A Win32 } + - { name: Windows-MSVC-x64, os: windows-latest, flags: -A x64 } - { name: Linux-x86_64, os: ubuntu-24.04, flags: -GNinja } - { name: Linux-arm64, os: ubuntu-24.04-arm, flags: -GNinja } - - { name: MacOS-arm, os: macos-latest } - - { name: MacOS-intel, os: macos-13 } + - { name: MacOS-arm64, os: macos-latest } + - { name: MacOS-x86_64, os: macos-13 } steps: - name: Setup Linux dependencies if: startsWith(runner.os, 'Linux') From 58a3f454af1cd7fc6bee75be1a358ce81d54a88a Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Thu, 27 Mar 2025 14:50:50 +0300 Subject: [PATCH 525/606] StartCDAudioPlaying(): change the local var pcm_frame into 32 bits Avoids new MSVC emitting __ftoul2_legacy() in x86 builds which we don't provide: Fixes https://github.com/libsdl-org/sdl12-compat/issues/352. --- src/SDL12_compat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 84a422c7b..521e3a9e4 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -9231,7 +9231,7 @@ StartCDAudioPlaying(SDL12_CD *cdrom, const int start_track, const int start_fram drmp3 *mp3 = (drmp3 *) SDL20_malloc(sizeof (drmp3)); const SDL_bool loaded = mp3 ? LoadCDTrack(start_track, mp3) : SDL_FALSE; const SDL_bool seeking = (loaded && (start_frame > 0))? SDL_TRUE : SDL_FALSE; - const drmp3_uint64 pcm_frame = seeking ? ((drmp3_uint64) ((start_frame / 75.0) * mp3->sampleRate)) : 0; + const drmp3_uint32 pcm_frame = seeking ? (Uint32) ((start_frame / 75.0) * (Sint32)mp3->sampleRate) : 0; if (!mp3) { return SDL20_OutOfMemory(); From f10920239783dc09bd22f09bad69585cfce8a28d Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Tue, 1 Apr 2025 19:41:00 +0300 Subject: [PATCH 526/606] Rename sdl12_compat.pc to sdl.pc sdl12-compat should be a drop-in replacement for SDL-1.2 so use the same pkg-config package name. c.f.: https://github.com/libsdl-org/sdl2-compat/pull/446 --- CMakeLists.txt | 7 +++---- sdl12_compat.pc.in => sdl.pc.in | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) rename sdl12_compat.pc.in => sdl.pc.in (87%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 57d9052e0..c70628adc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ # you can define SDL2_INCLUDE_DIR on the cmdline. For example: # cmake -DSDL2_INCLUDE_DIR=/opt/SDL2/include/SDL2 [other stuff] -cmake_minimum_required(VERSION 3.0.0...3.10) +cmake_minimum_required(VERSION 3.0...3.10) project(sdl12_compat VERSION 1.2.69 LANGUAGES C) @@ -40,7 +40,6 @@ if(APPLE) cmake_policy(SET CMP0068 NEW) # on macOS, don't let RPATH affect install_name. endif() endif() - if(WIN32) set(WIN32_SRCS "src/version.rc") endif() @@ -281,8 +280,8 @@ if(SDL12DEVEL) set(ENABLE_SHARED_TRUE "") set(ENABLE_SHARED_FALSE "#") - configure_file(sdl12_compat.pc.in sdl12_compat.pc @ONLY) - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/sdl12_compat.pc + configure_file(sdl.pc.in sdl.pc @ONLY) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/sdl.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig ) diff --git a/sdl12_compat.pc.in b/sdl.pc.in similarity index 87% rename from sdl12_compat.pc.in rename to sdl.pc.in index 30c5028a0..decd03edc 100644 --- a/sdl12_compat.pc.in +++ b/sdl.pc.in @@ -8,7 +8,7 @@ includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@ Name: sdl12_compat Description: An SDL-1.2 compatibility layer that uses SDL 2.0 behind the scenes. Version: @PROJECT_VERSION@ -Provides: sdl = @PROJECT_VERSION@ +Provides: sdl = @PROJECT_VERSION@, sdl12_compat = @PROJECT_VERSION@ Libs: -L${libdir} @SDL_RLD_FLAGS@ @SDL_LIBS@ @ENABLE_STATIC_TRUE@Libs.private: -L${libdir} @SDL_LIBS@ @SDL_STATIC_LIBS@ Cflags: -I${includedir}/SDL @SDL_CFLAGS@ From 1d3881a319ac2a61b502f9c8d895c6a19a658b8c Mon Sep 17 00:00:00 2001 From: Neal Gompa Date: Sun, 6 Apr 2025 17:07:19 -0400 Subject: [PATCH 527/606] Revert "Rename sdl12_compat.pc to sdl.pc" This is unnecessary, given that everyone uses pkgconf(1), which fully supports the "Provides:" stanza and expresses it in dependencies. This reverts commit f10920239783dc09bd22f09bad69585cfce8a28d. --- CMakeLists.txt | 7 ++++--- sdl.pc.in => sdl12_compat.pc.in | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) rename sdl.pc.in => sdl12_compat.pc.in (87%) diff --git a/CMakeLists.txt b/CMakeLists.txt index c70628adc..57d9052e0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ # you can define SDL2_INCLUDE_DIR on the cmdline. For example: # cmake -DSDL2_INCLUDE_DIR=/opt/SDL2/include/SDL2 [other stuff] -cmake_minimum_required(VERSION 3.0...3.10) +cmake_minimum_required(VERSION 3.0.0...3.10) project(sdl12_compat VERSION 1.2.69 LANGUAGES C) @@ -40,6 +40,7 @@ if(APPLE) cmake_policy(SET CMP0068 NEW) # on macOS, don't let RPATH affect install_name. endif() endif() + if(WIN32) set(WIN32_SRCS "src/version.rc") endif() @@ -280,8 +281,8 @@ if(SDL12DEVEL) set(ENABLE_SHARED_TRUE "") set(ENABLE_SHARED_FALSE "#") - configure_file(sdl.pc.in sdl.pc @ONLY) - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/sdl.pc + configure_file(sdl12_compat.pc.in sdl12_compat.pc @ONLY) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/sdl12_compat.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig ) diff --git a/sdl.pc.in b/sdl12_compat.pc.in similarity index 87% rename from sdl.pc.in rename to sdl12_compat.pc.in index decd03edc..30c5028a0 100644 --- a/sdl.pc.in +++ b/sdl12_compat.pc.in @@ -8,7 +8,7 @@ includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@ Name: sdl12_compat Description: An SDL-1.2 compatibility layer that uses SDL 2.0 behind the scenes. Version: @PROJECT_VERSION@ -Provides: sdl = @PROJECT_VERSION@, sdl12_compat = @PROJECT_VERSION@ +Provides: sdl = @PROJECT_VERSION@ Libs: -L${libdir} @SDL_RLD_FLAGS@ @SDL_LIBS@ @ENABLE_STATIC_TRUE@Libs.private: -L${libdir} @SDL_LIBS@ @SDL_STATIC_LIBS@ Cflags: -I${includedir}/SDL @SDL_CFLAGS@ From edf3883edb0e7d7c064f8d49ce3ffce66355fa47 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Wed, 9 Apr 2025 22:45:53 +0200 Subject: [PATCH 528/606] cmake: bump cmake policy level to latest CMake version Having higher CMake compatibility levels allows better integration with current CMake projects --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 57d9052e0..cc86e0db6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ # you can define SDL2_INCLUDE_DIR on the cmdline. For example: # cmake -DSDL2_INCLUDE_DIR=/opt/SDL2/include/SDL2 [other stuff] -cmake_minimum_required(VERSION 3.0.0...3.10) +cmake_minimum_required(VERSION 3.0.0...4.0) project(sdl12_compat VERSION 1.2.69 LANGUAGES C) From 0dca712d959267e5af50e6e2e3654f02ead32d97 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Wed, 9 Apr 2025 22:54:38 +0200 Subject: [PATCH 529/606] ci: do verbose build --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 9cf0d9693..3a2245654 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -32,5 +32,5 @@ jobs: - name: Configure CMake run: cmake -DSDL2_INCLUDE_DIR="${{ github.workspace }}/SDL2/include" -B build ${{ matrix.platform.flags }} - name: Build - run: cmake --build build/ + run: cmake --build build/ --verbose From f124ed8fbae19c8b02a94d2478bd0e59c46cfbba Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Wed, 9 Apr 2025 23:01:27 +0200 Subject: [PATCH 530/606] cmake: enable OBJC for CMake >= 3.16 --- CMakeLists.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index cc86e0db6..0516508c1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,6 +29,10 @@ set(CMAKE_SKIP_RPATH TRUE) if(APPLE) set(OSX_SRCS "src/SDL12_compat_objc.m") set_source_files_properties(${OSX_SRCS} PROPERTIES LANGUAGE C) + if(NOT CMAKE_VERSION VERSION_LESS "3.16") + enable_language(OBJC) + set_source_files_properties(${OSX_SRCS} PROPERTIES LANGUAGE OBJC) + endif() # compatibility version set to match SDL-1.2 autotools build # Xcode project file uses 1.0.0, but it's more compatible to use the # higher version. @@ -145,6 +149,9 @@ endif() if(APPLE) add_library(SDLmain STATIC src/SDLmain/macosx/SDLMain.m) set_source_files_properties(src/SDLmain/macosx/SDLMain.m PROPERTIES LANGUAGE C) + if(NOT CMAKE_VERSION VERSION_LESS "3.16") + set_source_files_properties("src/SDLmain/macosx/SDLMain.m" PROPERTIES LANGUAGE OBJC) + endif() elseif(WIN32) add_library(SDLmain STATIC src/SDLmain/win32/SDL_win32_main.c) set_target_properties(SDLmain PROPERTIES COMPILE_DEFINITIONS "_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE") # !!! FIXME: don't use C runtime? We fixed this in SDL2. From 2996daa5e2048a6502a335299cdec5d6393d70eb Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sun, 27 Apr 2025 23:35:20 +0300 Subject: [PATCH 531/606] update dr_mp3 from mainstream and adjust to its new api. --- src/SDL12_compat.c | 30 +- src/dr_mp3.h | 844 ++++++++++++++++++++++++++++++++++++--------- 2 files changed, 699 insertions(+), 175 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 521e3a9e4..1436fc40c 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -8858,6 +8858,9 @@ SDL_LoadWAV_RW(SDL12_RWops *rwops12, int freerwops12, static SDL_INLINE Sint64 SDLCALL SDL20_RWseek(SDL_RWops *ctx, Sint64 ofs, int whence) { return ctx->seek(ctx, ofs, whence); } +static SDL_INLINE Sint64 SDLCALL SDL20_RWtell(SDL_RWops *ctx) { + return ctx->seek(ctx, 0, RW_SEEK_CUR); +} static SDL_INLINE size_t SDLCALL SDL20_RWread(SDL_RWops *ctx, void *ptr, size_t size, size_t n) { return ctx->read(ctx, ptr, size, n); } @@ -8874,11 +8877,30 @@ mp3_sdlrwops_read(void *data, void *buf, size_t bytesToRead) static drmp3_bool32 mp3_sdlrwops_seek(void *data, int offset, drmp3_seek_origin origin) { - const int whence = (origin == drmp3_seek_origin_start) ? RW_SEEK_SET : RW_SEEK_CUR; - SDL_assert((origin == drmp3_seek_origin_start) || (origin == drmp3_seek_origin_current)); + int whence = (origin == drmp3_seek_origin_start) ? RW_SEEK_SET : RW_SEEK_CUR; + switch (origin) { + case drmp3_seek_origin_start: + whence = RW_SEEK_SET; + break; + case drmp3_seek_origin_current: + whence = RW_SEEK_CUR; + break; + case drmp3_seek_origin_end: + whence = RW_SEEK_END; + break; + default: + return DRMP3_FALSE; + } return (SDL20_RWseek((SDL_RWops *) data, offset, whence) == -1) ? DRMP3_FALSE : DRMP3_TRUE; } +static drmp3_bool32 +mp3_sdlrwops_tell(void *data, drmp3_int64 *pos) +{ + *pos = SDL20_RWtell((SDL_RWops *) data); + return (*pos != -1) ? DRMP3_TRUE : DRMP3_FALSE; +} + static SDL_bool OpenSDL2AudioDevice(SDL_AudioSpec *want); static int CloseSDL2AudioDevice(void); @@ -9081,7 +9103,7 @@ SDL_CDOpen(int drive) track = &retval->track[retval->numtracks]; if (!fake_data_track) { SDL_assert(rw != NULL); - if (!drmp3_init(mp3, mp3_sdlrwops_read, mp3_sdlrwops_seek, rw, NULL)) { + if (!drmp3_init(mp3, mp3_sdlrwops_read, mp3_sdlrwops_seek, mp3_sdlrwops_tell, NULL, rw, NULL)) { SDL20_RWclose(rw); rw = NULL; fake_data_track = SDL_TRUE; /* congratulations, bogus or unsupported MP3, you just became data! */ @@ -9212,7 +9234,7 @@ LoadCDTrack(const int tracknum, drmp3 *mp3) return SDL_FALSE; } - if (!drmp3_init(mp3, mp3_sdlrwops_read, mp3_sdlrwops_seek, rw, NULL)) { + if (!drmp3_init(mp3, mp3_sdlrwops_read, mp3_sdlrwops_seek, mp3_sdlrwops_tell, NULL, rw, NULL)) { SDL20_RWclose(rw); return SDL_FALSE; } diff --git a/src/dr_mp3.h b/src/dr_mp3.h index f07dcf5e7..e5c9aee67 100644 --- a/src/dr_mp3.h +++ b/src/dr_mp3.h @@ -1,6 +1,6 @@ /* MP3 audio decoder. Choice of public domain or MIT-0. See license statements at the end of this file. -dr_mp3 - v0.6.40 - 2024-12-17 +dr_mp3 - v0.7.0 - TBD David Reid - mackron@gmail.com @@ -9,29 +9,6 @@ GitHub: https://github.com/mackron/dr_libs Based on minimp3 (https://github.com/lieff/minimp3) which is where the real work was done. See the bottom of this file for differences between minimp3 and dr_mp3. */ -/* -RELEASE NOTES - VERSION 0.6 -=========================== -Version 0.6 includes breaking changes with the configuration of decoders. The ability to customize the number of output channels and the sample rate has been -removed. You must now use the channel count and sample rate reported by the MP3 stream itself, and all channel and sample rate conversion must be done -yourself. - - -Changes to Initialization -------------------------- -Previously, `drmp3_init()`, etc. took a pointer to a `drmp3_config` object that allowed you to customize the output channels and sample rate. This has been -removed. If you need the old behaviour you will need to convert the data yourself or just not upgrade. The following APIs have changed. - - `drmp3_init()` - `drmp3_init_memory()` - `drmp3_init_file()` - - -Miscellaneous Changes ---------------------- -Support for loading a file from a `wchar_t` string has been added via the `drmp3_init_file_w()` API. -*/ - /* Introduction ============= @@ -100,8 +77,8 @@ extern "C" { #define DRMP3_XSTRINGIFY(x) DRMP3_STRINGIFY(x) #define DRMP3_VERSION_MAJOR 0 -#define DRMP3_VERSION_MINOR 6 -#define DRMP3_VERSION_REVISION 40 +#define DRMP3_VERSION_MINOR 7 +#define DRMP3_VERSION_REVISION 0 #define DRMP3_VERSION_STRING DRMP3_XSTRINGIFY(DRMP3_VERSION_MAJOR) "." DRMP3_XSTRINGIFY(DRMP3_VERSION_MINOR) "." DRMP3_XSTRINGIFY(DRMP3_VERSION_REVISION) #include /* For size_t. */ @@ -139,6 +116,9 @@ typedef drmp3_uint8 drmp3_bool8; typedef drmp3_uint32 drmp3_bool32; #define DRMP3_TRUE 1 #define DRMP3_FALSE 0 + +/* Weird shifting syntax is for VC6 compatibility. */ +#define DRMP3_UINT64_MAX (((drmp3_uint64)0xFFFFFFFF << 32) | (drmp3_uint64)0xFFFFFFFF) /* End Sized Types */ /* Decorations */ @@ -160,7 +140,7 @@ typedef drmp3_uint32 drmp3_bool32; #endif #endif - #if defined(DR_MP3_IMPLEMENTATION) || defined(DRMP3_IMPLEMENTATION) + #if defined(DR_MP3_IMPLEMENTATION) #define DRMP3_API DRMP3_DLL_EXPORT #else #define DRMP3_API DRMP3_DLL_IMPORT @@ -285,7 +265,7 @@ Low Level Push API */ typedef struct { - int frame_bytes, channels, hz, layer, bitrate_kbps; + int frame_bytes, channels, sample_rate, layer, bitrate_kbps; } drmp3dec_frame_info; typedef struct @@ -314,7 +294,8 @@ Main API (Pull API) typedef enum { drmp3_seek_origin_start, - drmp3_seek_origin_current + drmp3_seek_origin_current, + drmp3_seek_origin_end } drmp3_seek_origin; typedef struct @@ -325,10 +306,27 @@ typedef struct drmp3_uint16 pcmFramesToDiscard; /* The number of leading samples to read and discard. These are discarded after mp3FramesToDiscard. */ } drmp3_seek_point; +typedef enum +{ + DRMP3_METADATA_TYPE_ID3V1, + DRMP3_METADATA_TYPE_ID3V2, + DRMP3_METADATA_TYPE_APE, + DRMP3_METADATA_TYPE_XING, + DRMP3_METADATA_TYPE_VBRI +} drmp3_metadata_type; + +typedef struct +{ + drmp3_metadata_type type; + const void* pRawData; /* A pointer to the raw data. */ + size_t rawDataSize; +} drmp3_metadata; + + /* Callback for when data is read. Return value is the number of bytes actually read. -pUserData [in] The user data that was passed to drmp3_init(), drmp3_open() and family. +pUserData [in] The user data that was passed to drmp3_init(), and family. pBufferOut [out] The output buffer. bytesToRead [in] The number of bytes to read. @@ -342,17 +340,33 @@ typedef size_t (* drmp3_read_proc)(void* pUserData, void* pBufferOut, size_t byt /* Callback for when data needs to be seeked. -pUserData [in] The user data that was passed to drmp3_init(), drmp3_open() and family. -offset [in] The number of bytes to move, relative to the origin. Will never be negative. -origin [in] The origin of the seek - the current position or the start of the stream. +pUserData [in] The user data that was passed to drmp3_init(), and family. +offset [in] The number of bytes to move, relative to the origin. Can be negative. +origin [in] The origin of the seek. Returns whether or not the seek was successful. - -Whether or not it is relative to the beginning or current position is determined by the "origin" parameter which -will be either drmp3_seek_origin_start or drmp3_seek_origin_current. */ typedef drmp3_bool32 (* drmp3_seek_proc)(void* pUserData, int offset, drmp3_seek_origin origin); +/* +Callback for retrieving the current cursor position. + +pUserData [in] The user data that was passed to drmp3_init(), and family. +pCursor [out] The cursor position in bytes from the start of the stream. + +Returns whether or not the cursor position was successfully retrieved. +*/ +typedef drmp3_bool32 (* drmp3_tell_proc)(void* pUserData, drmp3_int64* pCursor); + + +/* +Callback for when metadata is read. + +Only the raw data is provided. The client is responsible for parsing the contents of the data themsevles. +*/ +typedef void (* drmp3_meta_proc)(void* pUserData, const drmp3_metadata* pMetadata); + + typedef struct { drmp3_uint32 channels; @@ -366,22 +380,31 @@ typedef struct drmp3_uint32 sampleRate; drmp3_read_proc onRead; drmp3_seek_proc onSeek; + drmp3_meta_proc onMeta; void* pUserData; + void* pUserDataMeta; drmp3_allocation_callbacks allocationCallbacks; drmp3_uint32 mp3FrameChannels; /* The number of channels in the currently loaded MP3 frame. Internal use only. */ drmp3_uint32 mp3FrameSampleRate; /* The sample rate of the currently loaded MP3 frame. Internal use only. */ drmp3_uint32 pcmFramesConsumedInMP3Frame; drmp3_uint32 pcmFramesRemainingInMP3Frame; drmp3_uint8 pcmFrames[sizeof(float)*DRMP3_MAX_SAMPLES_PER_FRAME]; /* <-- Multipled by sizeof(float) to ensure there's enough room for DR_MP3_FLOAT_OUTPUT. */ - drmp3_uint64 currentPCMFrame; /* The current PCM frame, globally, based on the output sample rate. Mainly used for seeking. */ + drmp3_uint64 currentPCMFrame; /* The current PCM frame, globally. */ drmp3_uint64 streamCursor; /* The current byte the decoder is sitting on in the raw stream. */ + drmp3_uint64 streamLength; /* The length of the stream in bytes. dr_mp3 will not read beyond this. If a ID3v1 or APE tag is present, this will be set to the first byte of the tag. */ + drmp3_uint64 streamStartOffset; /* The offset of the start of the MP3 data. This is used for skipping ID3v2 and VBR tags. */ drmp3_seek_point* pSeekPoints; /* NULL by default. Set with drmp3_bind_seek_table(). Memory is owned by the client. dr_mp3 will never attempt to free this pointer. */ drmp3_uint32 seekPointCount; /* The number of items in pSeekPoints. When set to 0 assumes to no seek table. Defaults to zero. */ + drmp3_uint32 delayInPCMFrames; + drmp3_uint32 paddingInPCMFrames; + drmp3_uint64 totalPCMFrameCount; /* Set to DRMP3_UINT64_MAX if the length is unknown. Includes delay and padding. */ + drmp3_bool32 isVBR; + drmp3_bool32 isCBR; size_t dataSize; size_t dataCapacity; size_t dataConsumed; drmp3_uint8* pData; - drmp3_bool32 atEnd : 1; + drmp3_bool32 atEnd; struct { const drmp3_uint8* pData; @@ -395,6 +418,7 @@ Initializes an MP3 decoder. onRead [in] The function to call when data needs to be read from the client. onSeek [in] The function to call when the read position of the client data needs to move. +onTell [in] The function to call when the read position of the client data needs to be retrieved. pUserData [in, optional] A pointer to application defined data that will be passed to onRead and onSeek. Returns true if successful; false otherwise. @@ -403,7 +427,7 @@ Close the loader with drmp3_uninit(). See also: drmp3_init_file(), drmp3_init_memory(), drmp3_uninit() */ -DRMP3_API drmp3_bool32 drmp3_init(drmp3* pMP3, drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, const drmp3_allocation_callbacks* pAllocationCallbacks); +DRMP3_API drmp3_bool32 drmp3_init(drmp3* pMP3, drmp3_read_proc onRead, drmp3_seek_proc onSeek, drmp3_tell_proc onTell, drmp3_meta_proc onMeta, void* pUserData, const drmp3_allocation_callbacks* pAllocationCallbacks); /* Initializes an MP3 decoder from a block of memory. @@ -413,6 +437,7 @@ the lifetime of the drmp3 object. The buffer should contain the contents of the entire MP3 file. */ +DRMP3_API drmp3_bool32 drmp3_init_memory_with_metadata(drmp3* pMP3, const void* pData, size_t dataSize, drmp3_meta_proc onMeta, void* pUserDataMeta, const drmp3_allocation_callbacks* pAllocationCallbacks); DRMP3_API drmp3_bool32 drmp3_init_memory(drmp3* pMP3, const void* pData, size_t dataSize, const drmp3_allocation_callbacks* pAllocationCallbacks); #ifndef DR_MP3_NO_STDIO @@ -423,6 +448,9 @@ This holds the internal FILE object until drmp3_uninit() is called. Keep this in objects because the operating system may restrict the number of file handles an application can have open at any given time. */ +DRMP3_API drmp3_bool32 drmp3_init_file_with_metadata(drmp3* pMP3, const char* pFilePath, drmp3_meta_proc onMeta, void* pUserDataMeta, const drmp3_allocation_callbacks* pAllocationCallbacks); +DRMP3_API drmp3_bool32 drmp3_init_file_with_metadata_w(drmp3* pMP3, const wchar_t* pFilePath, drmp3_meta_proc onMeta, void* pUserDataMeta, const drmp3_allocation_callbacks* pAllocationCallbacks); + DRMP3_API drmp3_bool32 drmp3_init_file(drmp3* pMP3, const char* pFilePath, const drmp3_allocation_callbacks* pAllocationCallbacks); DRMP3_API drmp3_bool32 drmp3_init_file_w(drmp3* pMP3, const wchar_t* pFilePath, const drmp3_allocation_callbacks* pAllocationCallbacks); #endif @@ -505,9 +533,9 @@ On output pConfig will receive the channel count and sample rate of the stream. Free the returned pointer with drmp3_free(). */ -DRMP3_API float* drmp3_open_and_read_pcm_frames_f32(drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks); +DRMP3_API float* drmp3_open_and_read_pcm_frames_f32(drmp3_read_proc onRead, drmp3_seek_proc onSeek, drmp3_tell_proc onTell, void* pUserData, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks); #ifndef DR_MP3_NO_S16 -DRMP3_API drmp3_int16* drmp3_open_and_read_pcm_frames_s16(drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks); +DRMP3_API drmp3_int16* drmp3_open_and_read_pcm_frames_s16(drmp3_read_proc onRead, drmp3_seek_proc onSeek, drmp3_tell_proc onTell, void* pUserData, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks); #endif DRMP3_API float* drmp3_open_memory_and_read_pcm_frames_f32(const void* pData, size_t dataSize, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks); @@ -546,7 +574,7 @@ DRMP3_API void drmp3_free(void* p, const drmp3_allocation_callbacks* pAllocation ************************************************************************************************************************************************************ ************************************************************************************************************************************************************/ -#if defined(DR_MP3_IMPLEMENTATION) || defined(DRMP3_IMPLEMENTATION) +#if defined(DR_MP3_IMPLEMENTATION) #ifndef dr_mp3_c #define dr_mp3_c @@ -2313,7 +2341,7 @@ DRMP3_API int drmp3dec_decode_frame(drmp3dec *dec, const drmp3_uint8 *mp3, int m DRMP3_COPY_MEMORY(dec->header, hdr, DRMP3_HDR_SIZE); info->frame_bytes = i + frame_size; info->channels = DRMP3_HDR_IS_MONO(hdr) ? 1 : 2; - info->hz = drmp3_hdr_sample_rate_hz(hdr); + info->sample_rate = drmp3_hdr_sample_rate_hz(hdr); info->layer = 4 - DRMP3_HDR_GET_LAYER(hdr); info->bitrate_kbps = drmp3_hdr_bitrate_kbps(hdr); @@ -2607,14 +2635,48 @@ static drmp3_allocation_callbacks drmp3_copy_allocation_callbacks_or_defaults(co static size_t drmp3__on_read(drmp3* pMP3, void* pBufferOut, size_t bytesToRead) { - size_t bytesRead = pMP3->onRead(pMP3->pUserData, pBufferOut, bytesToRead); + size_t bytesRead; + + DRMP3_ASSERT(pMP3 != NULL); + DRMP3_ASSERT(pMP3->onRead != NULL); + + /* + Don't try reading 0 bytes from the callback. This can happen when the stream is clamped against + ID3v1 or APE tags at the end of the stream. + */ + if (bytesToRead == 0) { + return 0; + } + + bytesRead = pMP3->onRead(pMP3->pUserData, pBufferOut, bytesToRead); pMP3->streamCursor += bytesRead; + return bytesRead; } +static size_t drmp3__on_read_clamped(drmp3* pMP3, void* pBufferOut, size_t bytesToRead) +{ + DRMP3_ASSERT(pMP3 != NULL); + DRMP3_ASSERT(pMP3->onRead != NULL); + + if (pMP3->streamLength == DRMP3_UINT64_MAX) { + return drmp3__on_read(pMP3, pBufferOut, bytesToRead); + } else { + drmp3_uint64 bytesRemaining; + + bytesRemaining = (pMP3->streamLength - pMP3->streamCursor); + if (bytesToRead > bytesRemaining) { + bytesToRead = (size_t)bytesRemaining; + } + + return drmp3__on_read(pMP3, pBufferOut, bytesToRead); + } +} + static drmp3_bool32 drmp3__on_seek(drmp3* pMP3, int offset, drmp3_seek_origin origin) { DRMP3_ASSERT(offset >= 0); + DRMP3_ASSERT(origin == drmp3_seek_origin_start || origin == drmp3_seek_origin_current); if (!pMP3->onSeek(pMP3->pUserData, offset, origin)) { return DRMP3_FALSE; @@ -2622,7 +2684,7 @@ static drmp3_bool32 drmp3__on_seek(drmp3* pMP3, int offset, drmp3_seek_origin or if (origin == drmp3_seek_origin_start) { pMP3->streamCursor = (drmp3_uint64)offset; - } else { + } else{ pMP3->streamCursor += offset; } @@ -2635,7 +2697,6 @@ static drmp3_bool32 drmp3__on_seek_64(drmp3* pMP3, drmp3_uint64 offset, drmp3_se return drmp3__on_seek(pMP3, (int)offset, origin); } - /* Getting here "offset" is too large for a 32-bit integer. We just keep seeking forward until we hit the offset. */ if (!drmp3__on_seek(pMP3, 0x7FFFFFFF, drmp3_seek_origin_start)) { return DRMP3_FALSE; @@ -2659,8 +2720,22 @@ static drmp3_bool32 drmp3__on_seek_64(drmp3* pMP3, drmp3_uint64 offset, drmp3_se return DRMP3_TRUE; } +static void drmp3__on_meta(drmp3* pMP3, drmp3_metadata_type type, const void* pRawData, size_t rawDataSize) +{ + if (pMP3->onMeta) { + drmp3_metadata metadata; + + DRMP3_ZERO_OBJECT(&metadata); + metadata.type = type; + metadata.pRawData = pRawData; + metadata.rawDataSize = rawDataSize; + + pMP3->onMeta(pMP3->pUserDataMeta, &metadata); + } +} -static drmp3_uint32 drmp3_decode_next_frame_ex__callbacks(drmp3* pMP3, drmp3d_sample_t* pPCMFrames) + +static drmp3_uint32 drmp3_decode_next_frame_ex__callbacks(drmp3* pMP3, drmp3d_sample_t* pPCMFrames, drmp3dec_frame_info* pMP3FrameInfo, const drmp3_uint8** ppMP3FrameData) { drmp3_uint32 pcmFramesRead = 0; @@ -2700,7 +2775,7 @@ static drmp3_uint32 drmp3_decode_next_frame_ex__callbacks(drmp3* pMP3, drmp3d_sa pMP3->dataCapacity = newDataCap; } - bytesRead = drmp3__on_read(pMP3, pMP3->pData + pMP3->dataSize, (pMP3->dataCapacity - pMP3->dataSize)); + bytesRead = drmp3__on_read_clamped(pMP3, pMP3->pData + pMP3->dataSize, (pMP3->dataCapacity - pMP3->dataSize)); if (bytesRead == 0) { if (pMP3->dataSize == 0) { pMP3->atEnd = DRMP3_TRUE; @@ -2727,10 +2802,8 @@ static drmp3_uint32 drmp3_decode_next_frame_ex__callbacks(drmp3* pMP3, drmp3d_sa pcmFramesRead = drmp3dec_decode_frame(&pMP3->decoder, pMP3->pData + pMP3->dataConsumed, (int)pMP3->dataSize, pPCMFrames, &info); /* <-- Safe size_t -> int conversion thanks to the check above. */ /* Consume the data. */ - if (info.frame_bytes > 0) { - pMP3->dataConsumed += (size_t)info.frame_bytes; - pMP3->dataSize -= (size_t)info.frame_bytes; - } + pMP3->dataConsumed += (size_t)info.frame_bytes; + pMP3->dataSize -= (size_t)info.frame_bytes; /* pcmFramesRead will be equal to 0 if decoding failed. If it is zero and info.frame_bytes > 0 then we have successfully decoded the frame. */ if (pcmFramesRead > 0) { @@ -2738,7 +2811,16 @@ static drmp3_uint32 drmp3_decode_next_frame_ex__callbacks(drmp3* pMP3, drmp3d_sa pMP3->pcmFramesConsumedInMP3Frame = 0; pMP3->pcmFramesRemainingInMP3Frame = pcmFramesRead; pMP3->mp3FrameChannels = info.channels; - pMP3->mp3FrameSampleRate = info.hz; + pMP3->mp3FrameSampleRate = info.sample_rate; + + if (pMP3FrameInfo != NULL) { + *pMP3FrameInfo = info; + } + + if (ppMP3FrameData != NULL) { + *ppMP3FrameData = pMP3->pData + pMP3->dataConsumed - (size_t)info.frame_bytes; + } + break; } else if (info.frame_bytes == 0) { /* Need more data. minimp3 recommends doing data submission in 16K chunks. */ @@ -2765,7 +2847,7 @@ static drmp3_uint32 drmp3_decode_next_frame_ex__callbacks(drmp3* pMP3, drmp3d_sa } /* Fill in a chunk. */ - bytesRead = drmp3__on_read(pMP3, pMP3->pData + pMP3->dataSize, (pMP3->dataCapacity - pMP3->dataSize)); + bytesRead = drmp3__on_read_clamped(pMP3, pMP3->pData + pMP3->dataSize, (pMP3->dataCapacity - pMP3->dataSize)); if (bytesRead == 0) { pMP3->atEnd = DRMP3_TRUE; return 0; /* Error reading more data. */ @@ -2778,7 +2860,7 @@ static drmp3_uint32 drmp3_decode_next_frame_ex__callbacks(drmp3* pMP3, drmp3d_sa return pcmFramesRead; } -static drmp3_uint32 drmp3_decode_next_frame_ex__memory(drmp3* pMP3, drmp3d_sample_t* pPCMFrames) +static drmp3_uint32 drmp3_decode_next_frame_ex__memory(drmp3* pMP3, drmp3d_sample_t* pPCMFrames, drmp3dec_frame_info* pMP3FrameInfo, const drmp3_uint8** ppMP3FrameData) { drmp3_uint32 pcmFramesRead = 0; drmp3dec_frame_info info; @@ -2797,11 +2879,21 @@ static drmp3_uint32 drmp3_decode_next_frame_ex__memory(drmp3* pMP3, drmp3d_sampl pMP3->pcmFramesConsumedInMP3Frame = 0; pMP3->pcmFramesRemainingInMP3Frame = pcmFramesRead; pMP3->mp3FrameChannels = info.channels; - pMP3->mp3FrameSampleRate = info.hz; + pMP3->mp3FrameSampleRate = info.sample_rate; + + if (pMP3FrameInfo != NULL) { + *pMP3FrameInfo = info; + } + + if (ppMP3FrameData != NULL) { + *ppMP3FrameData = pMP3->memory.pData + pMP3->memory.currentReadPos; + } + break; } else if (info.frame_bytes > 0) { /* No frames were read, but it looks like we skipped past one. Read the next MP3 frame. */ pMP3->memory.currentReadPos += (size_t)info.frame_bytes; + pMP3->streamCursor += (size_t)info.frame_bytes; } else { /* Nothing at all was read. Abort. */ break; @@ -2810,23 +2902,24 @@ static drmp3_uint32 drmp3_decode_next_frame_ex__memory(drmp3* pMP3, drmp3d_sampl /* Consume the data. */ pMP3->memory.currentReadPos += (size_t)info.frame_bytes; + pMP3->streamCursor += (size_t)info.frame_bytes; return pcmFramesRead; } -static drmp3_uint32 drmp3_decode_next_frame_ex(drmp3* pMP3, drmp3d_sample_t* pPCMFrames) +static drmp3_uint32 drmp3_decode_next_frame_ex(drmp3* pMP3, drmp3d_sample_t* pPCMFrames, drmp3dec_frame_info* pMP3FrameInfo, const drmp3_uint8** ppMP3FrameData) { if (pMP3->memory.pData != NULL && pMP3->memory.dataSize > 0) { - return drmp3_decode_next_frame_ex__memory(pMP3, pPCMFrames); + return drmp3_decode_next_frame_ex__memory(pMP3, pPCMFrames, pMP3FrameInfo, ppMP3FrameData); } else { - return drmp3_decode_next_frame_ex__callbacks(pMP3, pPCMFrames); + return drmp3_decode_next_frame_ex__callbacks(pMP3, pPCMFrames, pMP3FrameInfo, ppMP3FrameData); } } static drmp3_uint32 drmp3_decode_next_frame(drmp3* pMP3) { DRMP3_ASSERT(pMP3 != NULL); - return drmp3_decode_next_frame_ex(pMP3, (drmp3d_sample_t*)pMP3->pcmFrames); + return drmp3_decode_next_frame_ex(pMP3, (drmp3d_sample_t*)pMP3->pcmFrames, NULL, NULL); } #if 0 @@ -2836,7 +2929,7 @@ static drmp3_uint32 drmp3_seek_next_frame(drmp3* pMP3) DRMP3_ASSERT(pMP3 != NULL); - pcmFrameCount = drmp3_decode_next_frame_ex(pMP3, NULL); + pcmFrameCount = drmp3_decode_next_frame_ex(pMP3, NULL, NULL, NULL); if (pcmFrameCount == 0) { return 0; } @@ -2850,8 +2943,13 @@ static drmp3_uint32 drmp3_seek_next_frame(drmp3* pMP3) } #endif -static drmp3_bool32 drmp3_init_internal(drmp3* pMP3, drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, const drmp3_allocation_callbacks* pAllocationCallbacks) +static drmp3_bool32 drmp3_init_internal(drmp3* pMP3, drmp3_read_proc onRead, drmp3_seek_proc onSeek, drmp3_tell_proc onTell, drmp3_meta_proc onMeta, void* pUserData, void* pUserDataMeta, const drmp3_allocation_callbacks* pAllocationCallbacks) { + drmp3dec_frame_info firstFrameInfo; + const drmp3_uint8* pFirstFrameData; + drmp3_uint32 firstFramePCMFrameCount; + drmp3_uint32 detectedMP3FrameCount = 0xFFFFFFFF; + DRMP3_ASSERT(pMP3 != NULL); DRMP3_ASSERT(onRead != NULL); @@ -2860,17 +2958,326 @@ static drmp3_bool32 drmp3_init_internal(drmp3* pMP3, drmp3_read_proc onRead, drm pMP3->onRead = onRead; pMP3->onSeek = onSeek; + pMP3->onMeta = onMeta; pMP3->pUserData = pUserData; + pMP3->pUserDataMeta = pUserDataMeta; pMP3->allocationCallbacks = drmp3_copy_allocation_callbacks_or_defaults(pAllocationCallbacks); if (pMP3->allocationCallbacks.onFree == NULL || (pMP3->allocationCallbacks.onMalloc == NULL && pMP3->allocationCallbacks.onRealloc == NULL)) { return DRMP3_FALSE; /* Invalid allocation callbacks. */ } - /* Decode the first frame to confirm that it is indeed a valid MP3 stream. */ - if (drmp3_decode_next_frame(pMP3) == 0) { + pMP3->streamCursor = 0; + pMP3->streamLength = DRMP3_UINT64_MAX; + pMP3->streamStartOffset = 0; + pMP3->delayInPCMFrames = 0; + pMP3->paddingInPCMFrames = 0; + pMP3->totalPCMFrameCount = DRMP3_UINT64_MAX; + + /* We'll first check for any ID3v1 or APE tags. */ + #if 1 + if (onSeek != NULL && onTell != NULL) { + if (onSeek(pUserData, 0, drmp3_seek_origin_end)) { + drmp3_int64 streamLen; + int streamEndOffset = 0; + + /* First get the length of the stream. We need this so we can ensure the stream is big enough to store the tags. */ + if (onTell(pUserData, &streamLen)) { + /* ID3v1 */ + if (streamLen > 128) { + char id3[3]; + if (onSeek(pUserData, streamEndOffset - 128, drmp3_seek_origin_end)) { + if (onRead(pUserData, id3, 3) == 3 && id3[0] == 'T' && id3[1] == 'A' && id3[2] == 'G') { + /* We have an ID3v1 tag. */ + streamEndOffset -= 128; + streamLen -= 128; + + /* Fire a metadata callback for the TAG data. */ + if (onMeta != NULL) { + drmp3_uint8 tag[128]; + tag[0] = 'T'; tag[1] = 'A'; tag[2] = 'G'; + + if (onRead(pUserData, tag + 3, 125) == 125) { + drmp3__on_meta(pMP3, DRMP3_METADATA_TYPE_ID3V1, tag, 128); + } + } + } else { + /* No ID3v1 tag. */ + } + } else { + /* Failed to seek to the ID3v1 tag. */ + } + } else { + /* Stream too short. No ID3v1 tag. */ + } + + /* APE */ + if (streamLen > 32) { + char ape[32]; /* The footer. */ + if (onSeek(pUserData, streamEndOffset - 32, drmp3_seek_origin_end)) { + if (onRead(pUserData, ape, 32) == 32 && ape[0] == 'A' && ape[1] == 'P' && ape[2] == 'E' && ape[3] == 'T' && ape[4] == 'A' && ape[5] == 'G' && ape[6] == 'E' && ape[7] == 'X') { + /* We have an APE tag. */ + drmp3_uint32 tagSize = + ((drmp3_uint32)ape[24] << 0) | + ((drmp3_uint32)ape[25] << 8) | + ((drmp3_uint32)ape[26] << 16) | + ((drmp3_uint32)ape[27] << 24); + + streamEndOffset -= 32 + tagSize; + streamLen -= 32 + tagSize; + + /* Fire a metadata callback for the APE data. Must include both the main content and footer. */ + if (onMeta != NULL) { + /* We first need to seek to the start of the APE tag. */ + if (onSeek(pUserData, streamEndOffset, drmp3_seek_origin_end)) { + size_t apeTagSize = (size_t)tagSize + 32; + drmp3_uint8* pTagData = (drmp3_uint8*)drmp3_malloc(apeTagSize, pAllocationCallbacks); + if (pTagData != NULL) { + if (onRead(pUserData, pTagData, apeTagSize) == apeTagSize) { + drmp3__on_meta(pMP3, DRMP3_METADATA_TYPE_APE, pTagData, apeTagSize); + } + + drmp3_free(pTagData, pAllocationCallbacks); + } + } + } + } + } + } else { + /* Stream too short. No APE tag. */ + } + + /* Seek back to the start. */ + if (!onSeek(pUserData, 0, drmp3_seek_origin_start)) { + return DRMP3_FALSE; /* Failed to seek back to the start. */ + } + + pMP3->streamLength = (drmp3_uint64)streamLen; + + if (pMP3->memory.pData != NULL) { + pMP3->memory.dataSize = (size_t)pMP3->streamLength; + } + } else { + /* Failed to get the length of the stream. ID3v1 and APE tags cannot be skipped. */ + if (!onSeek(pUserData, 0, drmp3_seek_origin_start)) { + return DRMP3_FALSE; /* Failed to seek back to the start. */ + } + } + } else { + /* Failed to seek to the end. Cannot skip ID3v1 or APE tags. */ + } + } else { + /* No onSeek or onTell callback. Cannot skip ID3v1 or APE tags. */ + } + #endif + + + /* ID3v2 tags */ + #if 1 + { + char header[10]; + if (onRead(pUserData, header, 10) == 10) { + if (header[0] == 'I' && header[1] == 'D' && header[2] == '3') { + drmp3_uint32 tagSize = + (((drmp3_uint32)header[6] & 0x7F) << 21) | + (((drmp3_uint32)header[7] & 0x7F) << 14) | + (((drmp3_uint32)header[8] & 0x7F) << 7) | + (((drmp3_uint32)header[9] & 0x7F) << 0); + + /* Account for the footer. */ + if (header[5] & 0x10) { + tagSize += 10; + } + + /* Read the tag content and fire a metadata callback. */ + if (onMeta != NULL) { + size_t tagSizeWithHeader = 10 + tagSize; + drmp3_uint8* pTagData = (drmp3_uint8*)drmp3_malloc(tagSizeWithHeader, pAllocationCallbacks); + if (pTagData != NULL) { + DRMP3_COPY_MEMORY(pTagData, header, 10); + + if (onRead(pUserData, pTagData + 10, tagSize) == tagSize) { + drmp3__on_meta(pMP3, DRMP3_METADATA_TYPE_ID3V2, pTagData, tagSizeWithHeader); + } + + drmp3_free(pTagData, pAllocationCallbacks); + } + } else { + /* Don't have a metadata callback, so just skip the tag. */ + if (onSeek != NULL) { + if (!onSeek(pUserData, tagSize, drmp3_seek_origin_current)) { + return DRMP3_FALSE; /* Failed to seek past the ID3v2 tag. */ + } + } else { + /* Don't have a seek callback. Read and discard. */ + char discard[1024]; + + while (tagSize > 0) { + size_t bytesToRead = tagSize; + if (bytesToRead > sizeof(discard)) { + bytesToRead = sizeof(discard); + } + + if (onRead(pUserData, discard, bytesToRead) != bytesToRead) { + return DRMP3_FALSE; /* Failed to read data. */ + } + + tagSize -= (drmp3_uint32)bytesToRead; + } + } + } + + pMP3->streamStartOffset += 10 + tagSize; /* +10 for the header. */ + pMP3->streamCursor = pMP3->streamStartOffset; + } else { + /* Not an ID3v2 tag. Seek back to the start. */ + if (onSeek != NULL) { + if (!onSeek(pUserData, 0, drmp3_seek_origin_start)) { + return DRMP3_FALSE; /* Failed to seek back to the start. */ + } + } else { + /* Don't have a seek callback to move backwards. We'll just fall through and let the decoding process re-sync. The ideal solution here would be to read into the cache. */ + + /* + TODO: Copy the header into the cache. Will need to allocate space. See drmp3_decode_next_frame_ex__callbacks. There is not need + to handle the memory case because that will always have a seek implementation and will never hit this code path. + */ + } + } + } else { + /* Failed to read the header. We can return false here. If we couldn't read 10 bytes there's no way we'll have a valid MP3 stream. */ + return DRMP3_FALSE; + } + } + #endif + + /* + Decode the first frame to confirm that it is indeed a valid MP3 stream. Note that it's possible the first frame + is actually a Xing/LAME/VBRI header. If this is the case we need to skip over it. + */ + firstFramePCMFrameCount = drmp3_decode_next_frame_ex(pMP3, (drmp3d_sample_t*)pMP3->pcmFrames, &firstFrameInfo, &pFirstFrameData); + if (firstFramePCMFrameCount > 0) { + DRMP3_ASSERT(pFirstFrameData != NULL); + + /* + It might be a header. If so, we need to clear out the cached PCM frames in order to trigger a reload of fresh + data when decoding starts. We can assume all validation has already been performed to check if this is a valid + MP3 frame and that there is more than 0 bytes making up the frame. + + We're going to be basing this parsing code off the minimp3_ex implementation. + */ + #if 1 + DRMP3_ASSERT(firstFrameInfo.frame_bytes > 0); + { + drmp3_bs bs; + drmp3_L3_gr_info grInfo[4]; + const drmp3_uint8* pTagData = pFirstFrameData; + + drmp3_bs_init(&bs, pFirstFrameData + DRMP3_HDR_SIZE, firstFrameInfo.frame_bytes - DRMP3_HDR_SIZE); + + if (DRMP3_HDR_IS_CRC(pFirstFrameData)) { + drmp3_bs_get_bits(&bs, 16); /* CRC. */ + } + + if (drmp3_L3_read_side_info(&bs, grInfo, pFirstFrameData) >= 0) { + drmp3_bool32 isXing = DRMP3_FALSE; + drmp3_bool32 isInfo = DRMP3_FALSE; + const drmp3_uint8* pTagDataBeg; + + pTagDataBeg = pFirstFrameData + DRMP3_HDR_SIZE + (bs.pos/8); + pTagData = pTagDataBeg; + + /* Check for both "Xing" and "Info" identifiers. */ + isXing = (pTagData[0] == 'X' && pTagData[1] == 'i' && pTagData[2] == 'n' && pTagData[3] == 'g'); + isInfo = (pTagData[0] == 'I' && pTagData[1] == 'n' && pTagData[2] == 'f' && pTagData[3] == 'o'); + + if (isXing || isInfo) { + drmp3_uint32 bytes = 0; + drmp3_uint32 flags = pTagData[7]; + + pTagData += 8; /* Skip past the ID and flags. */ + + if (flags & 0x01) { /* FRAMES flag. */ + detectedMP3FrameCount = (drmp3_uint32)pTagData[0] << 24 | (drmp3_uint32)pTagData[1] << 16 | (drmp3_uint32)pTagData[2] << 8 | (drmp3_uint32)pTagData[3]; + pTagData += 4; + } + + if (flags & 0x02) { /* BYTES flag. */ + bytes = (drmp3_uint32)pTagData[0] << 24 | (drmp3_uint32)pTagData[1] << 16 | (drmp3_uint32)pTagData[2] << 8 | (drmp3_uint32)pTagData[3]; + (void)bytes; /* <-- Just to silence a warning about `bytes` being assigned but unused. Want to leave this here in case I want to make use of it later. */ + pTagData += 4; + } + + if (flags & 0x04) { /* TOC flag. */ + /* TODO: Extract and bind seek points. */ + pTagData += 100; + } + + if (flags & 0x08) { /* SCALE flag. */ + pTagData += 4; + } + + /* At this point we're done with the Xing/Info header. Now we can look at the LAME data. */ + if (pTagData[0]) { + pTagData += 21; + + if (pTagData - pFirstFrameData + 14 < firstFrameInfo.frame_bytes) { + int delayInPCMFrames; + int paddingInPCMFrames; + + delayInPCMFrames = (( (drmp3_uint32)pTagData[0] << 4) | ((drmp3_uint32)pTagData[1] >> 4)) + (528 + 1); + paddingInPCMFrames = ((((drmp3_uint32)pTagData[1] & 0xF) << 8) | ((drmp3_uint32)pTagData[2] )) - (528 + 1); + if (paddingInPCMFrames < 0) { + paddingInPCMFrames = 0; /* Padding cannot be negative. Probably a malformed file. Ignore. */ + } + + pMP3->delayInPCMFrames = (drmp3_uint32)delayInPCMFrames; + pMP3->paddingInPCMFrames = (drmp3_uint32)paddingInPCMFrames; + } + } + + /* + My understanding is that if the "Xing" header is present we can consider this to be a VBR stream and if the "Info" header is + present it's a CBR stream. If this is not the case let me know! I'm just tracking this for the time being in case I want to + look at doing some CBR optimizations later on, such as faster seeking. + */ + if (isXing) { + pMP3->isVBR = DRMP3_TRUE; + } else if (isInfo) { + pMP3->isCBR = DRMP3_TRUE; + } + + /* Post the raw data of the tag to the metadata callback. */ + if (onMeta != NULL) { + drmp3_metadata_type metadataType = isXing ? DRMP3_METADATA_TYPE_XING : DRMP3_METADATA_TYPE_VBRI; + size_t tagDataSize; + + tagDataSize = (size_t)firstFrameInfo.frame_bytes; + tagDataSize -= (size_t)(pTagDataBeg - pFirstFrameData); + + drmp3__on_meta(pMP3, metadataType, pTagDataBeg, tagDataSize); + } + + /* Since this was identified as a tag, we don't want to treat it as audio. We need to clear out the PCM cache. */ + pMP3->pcmFramesRemainingInMP3Frame = 0; + + /* The start offset needs to be moved to the end of this frame so it's not included in any audio processing after seeking. */ + pMP3->streamStartOffset += (drmp3_uint32)(firstFrameInfo.frame_bytes); + pMP3->streamCursor = pMP3->streamStartOffset; + } + } else { + /* Failed to read the side info. */ + } + } + #endif + } else { + /* Not a valid MP3 stream. */ drmp3__free_from_callbacks(pMP3->pData, &pMP3->allocationCallbacks); /* The call above may have allocated memory. Need to make sure it's freed before aborting. */ - return DRMP3_FALSE; /* Not a valid MP3 stream. */ + return DRMP3_FALSE; + } + + if (detectedMP3FrameCount != 0xFFFFFFFF) { + pMP3->totalPCMFrameCount = detectedMP3FrameCount * firstFramePCMFrameCount; } pMP3->channels = pMP3->mp3FrameChannels; @@ -2879,14 +3286,14 @@ static drmp3_bool32 drmp3_init_internal(drmp3* pMP3, drmp3_read_proc onRead, drm return DRMP3_TRUE; } -DRMP3_API drmp3_bool32 drmp3_init(drmp3* pMP3, drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, const drmp3_allocation_callbacks* pAllocationCallbacks) +DRMP3_API drmp3_bool32 drmp3_init(drmp3* pMP3, drmp3_read_proc onRead, drmp3_seek_proc onSeek, drmp3_tell_proc onTell, drmp3_meta_proc onMeta, void* pUserData, const drmp3_allocation_callbacks* pAllocationCallbacks) { if (pMP3 == NULL || onRead == NULL) { return DRMP3_FALSE; } DRMP3_ZERO_OBJECT(pMP3); - return drmp3_init_internal(pMP3, onRead, onSeek, pUserData, pAllocationCallbacks); + return drmp3_init_internal(pMP3, onRead, onSeek, onTell, onMeta, pUserData, pUserData, pAllocationCallbacks); } @@ -2920,29 +3327,52 @@ static drmp3_bool32 drmp3__on_seek_memory(void* pUserData, int byteOffset, drmp3 if (origin == drmp3_seek_origin_current) { if (byteOffset > 0) { if (pMP3->memory.currentReadPos + byteOffset > pMP3->memory.dataSize) { - byteOffset = (int)(pMP3->memory.dataSize - pMP3->memory.currentReadPos); /* Trying to seek too far forward. */ + return DRMP3_FALSE; /* Trying to seek too far forward. */ } } else { if (pMP3->memory.currentReadPos < (size_t)-byteOffset) { - byteOffset = -(int)pMP3->memory.currentReadPos; /* Trying to seek too far backwards. */ + return DRMP3_FALSE; /* Trying to seek too far backwards. */ } } /* This will never underflow thanks to the clamps above. */ pMP3->memory.currentReadPos += byteOffset; - } else { + } else if (origin == drmp3_seek_origin_start) { if ((drmp3_uint32)byteOffset <= pMP3->memory.dataSize) { pMP3->memory.currentReadPos = byteOffset; } else { - pMP3->memory.currentReadPos = pMP3->memory.dataSize; /* Trying to seek too far forward. */ + return DRMP3_FALSE; /* Trying to seek too far forward. */ + } + } else if (origin == drmp3_seek_origin_end) { + if (byteOffset > 0) { + return DRMP3_FALSE; /* Trying to seek beyond the end of the buffer. */ } + + if ((size_t)(-byteOffset) > pMP3->memory.dataSize) { + return DRMP3_FALSE; /* Trying to seek too far back. */ + } + + pMP3->memory.currentReadPos = pMP3->memory.dataSize - (size_t)(-byteOffset); } return DRMP3_TRUE; } -DRMP3_API drmp3_bool32 drmp3_init_memory(drmp3* pMP3, const void* pData, size_t dataSize, const drmp3_allocation_callbacks* pAllocationCallbacks) +static drmp3_bool32 drmp3__on_tell_memory(void* pUserData, drmp3_int64* pCursor) { + drmp3* pMP3 = (drmp3*)pUserData; + + DRMP3_ASSERT(pMP3 != NULL); + DRMP3_ASSERT(pCursor != NULL); + + *pCursor = (drmp3_int64)pMP3->memory.currentReadPos; + return DRMP3_TRUE; +} + +DRMP3_API drmp3_bool32 drmp3_init_memory_with_metadata(drmp3* pMP3, const void* pData, size_t dataSize, drmp3_meta_proc onMeta, void* pUserDataMeta, const drmp3_allocation_callbacks* pAllocationCallbacks) +{ + drmp3_bool32 result; + if (pMP3 == NULL) { return DRMP3_FALSE; } @@ -2957,7 +3387,26 @@ DRMP3_API drmp3_bool32 drmp3_init_memory(drmp3* pMP3, const void* pData, size_t pMP3->memory.dataSize = dataSize; pMP3->memory.currentReadPos = 0; - return drmp3_init_internal(pMP3, drmp3__on_read_memory, drmp3__on_seek_memory, pMP3, pAllocationCallbacks); + result = drmp3_init_internal(pMP3, drmp3__on_read_memory, drmp3__on_seek_memory, drmp3__on_tell_memory, onMeta, pMP3, pUserDataMeta, pAllocationCallbacks); + if (result == DRMP3_FALSE) { + return DRMP3_FALSE; + } + + /* Adjust the length of the memory stream to account for ID3v1 and APE tags. */ + if (pMP3->streamLength <= (drmp3_uint64)DRMP3_SIZE_MAX) { + pMP3->memory.dataSize = (size_t)pMP3->streamLength; /* Safe cast. */ + } + + if (pMP3->streamStartOffset > (drmp3_uint64)DRMP3_SIZE_MAX) { + return DRMP3_FALSE; /* Tags too big. */ + } + + return DRMP3_TRUE; +} + +DRMP3_API drmp3_bool32 drmp3_init_memory(drmp3* pMP3, const void* pData, size_t dataSize, const drmp3_allocation_callbacks* pAllocationCallbacks) +{ + return drmp3_init_memory_with_metadata(pMP3, pData, dataSize, NULL, NULL, pAllocationCallbacks); } @@ -3087,7 +3536,7 @@ static drmp3_result drmp3_result_from_errno(int e) #ifdef ENOSYS case ENOSYS: return DRMP3_NOT_IMPLEMENTED; #endif - #ifdef ENOTEMPTY + #if defined(ENOTEMPTY) && ENOTEMPTY != EEXIST /* In AIX, ENOTEMPTY and EEXIST use the same value. */ case ENOTEMPTY: return DRMP3_DIRECTORY_NOT_EMPTY; #endif #ifdef ELOOP @@ -3537,19 +3986,56 @@ static size_t drmp3__on_read_stdio(void* pUserData, void* pBufferOut, size_t byt static drmp3_bool32 drmp3__on_seek_stdio(void* pUserData, int offset, drmp3_seek_origin origin) { - return fseek((FILE*)pUserData, offset, (origin == drmp3_seek_origin_current) ? SEEK_CUR : SEEK_SET) == 0; + int whence = SEEK_SET; + if (origin == drmp3_seek_origin_current) { + whence = SEEK_CUR; + } else if (origin == drmp3_seek_origin_end) { + whence = SEEK_END; + } + + return fseek((FILE*)pUserData, offset, whence) == 0; } -DRMP3_API drmp3_bool32 drmp3_init_file(drmp3* pMP3, const char* pFilePath, const drmp3_allocation_callbacks* pAllocationCallbacks) +static drmp3_bool32 drmp3__on_tell_stdio(void* pUserData, drmp3_int64* pCursor) +{ + FILE* pFileStdio = (FILE*)pUserData; + drmp3_int64 result; + + /* These were all validated at a higher level. */ + DRMP3_ASSERT(pFileStdio != NULL); + DRMP3_ASSERT(pCursor != NULL); + +#if defined(_WIN32) + #if defined(_MSC_VER) && _MSC_VER > 1200 + result = _ftelli64(pFileStdio); + #else + result = ftell(pFileStdio); + #endif +#else + result = ftell(pFileStdio); +#endif + + *pCursor = result; + + return DRMP3_TRUE; +} + +DRMP3_API drmp3_bool32 drmp3_init_file_with_metadata(drmp3* pMP3, const char* pFilePath, drmp3_meta_proc onMeta, void* pUserDataMeta, const drmp3_allocation_callbacks* pAllocationCallbacks) { drmp3_bool32 result; FILE* pFile; + if (pMP3 == NULL) { + return DRMP3_FALSE; + } + + DRMP3_ZERO_OBJECT(pMP3); + if (drmp3_fopen(&pFile, pFilePath, "rb") != DRMP3_SUCCESS) { return DRMP3_FALSE; } - result = drmp3_init(pMP3, drmp3__on_read_stdio, drmp3__on_seek_stdio, (void*)pFile, pAllocationCallbacks); + result = drmp3_init_internal(pMP3, drmp3__on_read_stdio, drmp3__on_seek_stdio, drmp3__on_tell_stdio, onMeta, (void*)pFile, pUserDataMeta, pAllocationCallbacks); if (result != DRMP3_TRUE) { fclose(pFile); return result; @@ -3558,16 +4044,22 @@ DRMP3_API drmp3_bool32 drmp3_init_file(drmp3* pMP3, const char* pFilePath, const return DRMP3_TRUE; } -DRMP3_API drmp3_bool32 drmp3_init_file_w(drmp3* pMP3, const wchar_t* pFilePath, const drmp3_allocation_callbacks* pAllocationCallbacks) +DRMP3_API drmp3_bool32 drmp3_init_file_with_metadata_w(drmp3* pMP3, const wchar_t* pFilePath, drmp3_meta_proc onMeta, void* pUserDataMeta, const drmp3_allocation_callbacks* pAllocationCallbacks) { drmp3_bool32 result; FILE* pFile; + if (pMP3 == NULL) { + return DRMP3_FALSE; + } + + DRMP3_ZERO_OBJECT(pMP3); + if (drmp3_wfopen(&pFile, pFilePath, L"rb", pAllocationCallbacks) != DRMP3_SUCCESS) { return DRMP3_FALSE; } - result = drmp3_init(pMP3, drmp3__on_read_stdio, drmp3__on_seek_stdio, (void*)pFile, pAllocationCallbacks); + result = drmp3_init_internal(pMP3, drmp3__on_read_stdio, drmp3__on_seek_stdio, drmp3__on_tell_stdio, onMeta, (void*)pFile, pUserDataMeta, pAllocationCallbacks); if (result != DRMP3_TRUE) { fclose(pFile); return result; @@ -3575,6 +4067,16 @@ DRMP3_API drmp3_bool32 drmp3_init_file_w(drmp3* pMP3, const wchar_t* pFilePath, return DRMP3_TRUE; } + +DRMP3_API drmp3_bool32 drmp3_init_file(drmp3* pMP3, const char* pFilePath, const drmp3_allocation_callbacks* pAllocationCallbacks) +{ + return drmp3_init_file_with_metadata(pMP3, pFilePath, NULL, NULL, pAllocationCallbacks); +} + +DRMP3_API drmp3_bool32 drmp3_init_file_w(drmp3* pMP3, const wchar_t* pFilePath, const drmp3_allocation_callbacks* pAllocationCallbacks) +{ + return drmp3_init_file_with_metadata_w(pMP3, pFilePath, NULL, NULL, pAllocationCallbacks); +} #endif DRMP3_API void drmp3_uninit(drmp3* pMP3) @@ -3663,19 +4165,48 @@ static drmp3_uint64 drmp3_read_pcm_frames_raw(drmp3* pMP3, drmp3_uint64 framesTo DRMP3_ASSERT(pMP3->onRead != NULL); while (framesToRead > 0) { - drmp3_uint32 framesToConsume = (drmp3_uint32)DRMP3_MIN(pMP3->pcmFramesRemainingInMP3Frame, framesToRead); + drmp3_uint32 framesToConsume; + + /* Skip frames if necessary. */ + if (pMP3->currentPCMFrame < pMP3->delayInPCMFrames) { + drmp3_uint32 framesToSkip = (drmp3_uint32)DRMP3_MIN(pMP3->pcmFramesRemainingInMP3Frame, pMP3->delayInPCMFrames - pMP3->currentPCMFrame); + + pMP3->currentPCMFrame += framesToSkip; + pMP3->pcmFramesConsumedInMP3Frame += framesToSkip; + pMP3->pcmFramesRemainingInMP3Frame -= framesToSkip; + } + + framesToConsume = (drmp3_uint32)DRMP3_MIN(pMP3->pcmFramesRemainingInMP3Frame, framesToRead); + + /* Clamp the number of frames to read to the padding. */ + if (pMP3->totalPCMFrameCount != DRMP3_UINT64_MAX && pMP3->totalPCMFrameCount > pMP3->paddingInPCMFrames) { + if (pMP3->currentPCMFrame < (pMP3->totalPCMFrameCount - pMP3->paddingInPCMFrames)) { + drmp3_uint64 framesRemainigToPadding = (pMP3->totalPCMFrameCount - pMP3->paddingInPCMFrames) - pMP3->currentPCMFrame; + if (framesToConsume > framesRemainigToPadding) { + framesToConsume = (drmp3_uint32)framesRemainigToPadding; + } + } else { + /* We're into the padding. Abort. */ + break; + } + } + if (pBufferOut != NULL) { - #if defined(DR_MP3_FLOAT_OUTPUT) - /* f32 */ - float* pFramesOutF32 = (float*)DRMP3_OFFSET_PTR(pBufferOut, sizeof(float) * totalFramesRead * pMP3->channels); - float* pFramesInF32 = (float*)DRMP3_OFFSET_PTR(&pMP3->pcmFrames[0], sizeof(float) * pMP3->pcmFramesConsumedInMP3Frame * pMP3->mp3FrameChannels); - DRMP3_COPY_MEMORY(pFramesOutF32, pFramesInF32, sizeof(float) * framesToConsume * pMP3->channels); - #else - /* s16 */ - drmp3_int16* pFramesOutS16 = (drmp3_int16*)DRMP3_OFFSET_PTR(pBufferOut, sizeof(drmp3_int16) * totalFramesRead * pMP3->channels); - drmp3_int16* pFramesInS16 = (drmp3_int16*)DRMP3_OFFSET_PTR(&pMP3->pcmFrames[0], sizeof(drmp3_int16) * pMP3->pcmFramesConsumedInMP3Frame * pMP3->mp3FrameChannels); - DRMP3_COPY_MEMORY(pFramesOutS16, pFramesInS16, sizeof(drmp3_int16) * framesToConsume * pMP3->channels); - #endif + #if defined(DR_MP3_FLOAT_OUTPUT) + { + /* f32 */ + float* pFramesOutF32 = (float*)DRMP3_OFFSET_PTR(pBufferOut, sizeof(float) * totalFramesRead * pMP3->channels); + float* pFramesInF32 = (float*)DRMP3_OFFSET_PTR(&pMP3->pcmFrames[0], sizeof(float) * pMP3->pcmFramesConsumedInMP3Frame * pMP3->mp3FrameChannels); + DRMP3_COPY_MEMORY(pFramesOutF32, pFramesInF32, sizeof(float) * framesToConsume * pMP3->channels); + } + #else + { + /* s16 */ + drmp3_int16* pFramesOutS16 = (drmp3_int16*)DRMP3_OFFSET_PTR(pBufferOut, sizeof(drmp3_int16) * totalFramesRead * pMP3->channels); + drmp3_int16* pFramesInS16 = (drmp3_int16*)DRMP3_OFFSET_PTR(&pMP3->pcmFrames[0], sizeof(drmp3_int16) * pMP3->pcmFramesConsumedInMP3Frame * pMP3->mp3FrameChannels); + DRMP3_COPY_MEMORY(pFramesOutS16, pFramesInS16, sizeof(drmp3_int16) * framesToConsume * pMP3->channels); + } + #endif } pMP3->currentPCMFrame += framesToConsume; @@ -3688,12 +4219,14 @@ static drmp3_uint64 drmp3_read_pcm_frames_raw(drmp3* pMP3, drmp3_uint64 framesTo break; } + /* If the cursor is already at the padding we need to abort. */ + if (pMP3->totalPCMFrameCount != DRMP3_UINT64_MAX && pMP3->totalPCMFrameCount > pMP3->paddingInPCMFrames && pMP3->currentPCMFrame >= (pMP3->totalPCMFrameCount - pMP3->paddingInPCMFrames)) { + break; + } + DRMP3_ASSERT(pMP3->pcmFramesRemainingInMP3Frame == 0); - /* - At this point we have exhausted our in-memory buffer so we need to re-fill. Note that the sample rate may have changed - at this point which means we'll also need to update our sample rate conversion pipeline. - */ + /* At this point we have exhausted our in-memory buffer so we need to re-fill. */ if (drmp3_decode_next_frame(pMP3) == 0) { break; } @@ -3797,7 +4330,7 @@ static drmp3_bool32 drmp3_seek_to_start_of_stream(drmp3* pMP3) DRMP3_ASSERT(pMP3->onSeek != NULL); /* Seek to the start of the stream to begin with. */ - if (!drmp3__on_seek(pMP3, 0, drmp3_seek_origin_start)) { + if (!drmp3__on_seek_64(pMP3, pMP3->streamStartOffset, drmp3_seek_origin_start)) { return DRMP3_FALSE; } @@ -3916,7 +4449,7 @@ static drmp3_bool32 drmp3_seek_to_pcm_frame__seek_table(drmp3* pMP3, drmp3_uint6 } /* We first need to decode the next frame. */ - pcmFramesRead = drmp3_decode_next_frame_ex(pMP3, pPCMFrames); + pcmFramesRead = drmp3_decode_next_frame_ex(pMP3, pPCMFrames, NULL, NULL); if (pcmFramesRead == 0) { return DRMP3_FALSE; } @@ -3984,7 +4517,7 @@ DRMP3_API drmp3_bool32 drmp3_get_mp3_and_pcm_frame_count(drmp3* pMP3, drmp3_uint for (;;) { drmp3_uint32 pcmFramesInCurrentMP3Frame; - pcmFramesInCurrentMP3Frame = drmp3_decode_next_frame_ex(pMP3, NULL); + pcmFramesInCurrentMP3Frame = drmp3_decode_next_frame_ex(pMP3, NULL, NULL, NULL); if (pcmFramesInCurrentMP3Frame == 0) { break; } @@ -4015,11 +4548,35 @@ DRMP3_API drmp3_bool32 drmp3_get_mp3_and_pcm_frame_count(drmp3* pMP3, drmp3_uint DRMP3_API drmp3_uint64 drmp3_get_pcm_frame_count(drmp3* pMP3) { drmp3_uint64 totalPCMFrameCount; - if (!drmp3_get_mp3_and_pcm_frame_count(pMP3, NULL, &totalPCMFrameCount)) { + + if (pMP3 == NULL) { return 0; } - return totalPCMFrameCount; + if (pMP3->totalPCMFrameCount != DRMP3_UINT64_MAX) { + totalPCMFrameCount = pMP3->totalPCMFrameCount; + + if (totalPCMFrameCount >= pMP3->delayInPCMFrames) { + totalPCMFrameCount -= pMP3->delayInPCMFrames; + } else { + /* The delay is greater than the frame count reported by the Xing/Info tag. Assume it's invalid and ignore. */ + } + + if (totalPCMFrameCount >= pMP3->paddingInPCMFrames) { + totalPCMFrameCount -= pMP3->paddingInPCMFrames; + } else { + /* The padding is greater than the frame count reported by the Xing/Info tag. Assume it's invalid and ignore. */ + } + + return totalPCMFrameCount; + } else { + /* Unknown frame count. Need to calculate it. */ + if (!drmp3_get_mp3_and_pcm_frame_count(pMP3, NULL, &totalPCMFrameCount)) { + return 0; + } + + return totalPCMFrameCount; + } } DRMP3_API drmp3_uint64 drmp3_get_mp3_frame_count(drmp3* pMP3) @@ -4122,7 +4679,7 @@ DRMP3_API drmp3_bool32 drmp3_calculate_seek_points(drmp3* pMP3, drmp3_uint32* pS mp3FrameInfo[iMP3Frame].pcmFrameIndex = runningPCMFrameCount; /* We need to get information about this frame so we can know how many samples it contained. */ - pcmFramesInCurrentMP3FrameIn = drmp3_decode_next_frame_ex(pMP3, NULL); + pcmFramesInCurrentMP3FrameIn = drmp3_decode_next_frame_ex(pMP3, NULL, NULL, NULL); if (pcmFramesInCurrentMP3FrameIn == 0) { return DRMP3_FALSE; /* This should never happen. */ } @@ -4166,7 +4723,7 @@ DRMP3_API drmp3_bool32 drmp3_calculate_seek_points(drmp3* pMP3, drmp3_uint32* pS Go to the next MP3 frame. This shouldn't ever fail, but just in case it does we just set the seek point and break. If it happens, it should only ever do it for the last seek point. */ - pcmFramesInCurrentMP3FrameIn = drmp3_decode_next_frame_ex(pMP3, NULL); + pcmFramesInCurrentMP3FrameIn = drmp3_decode_next_frame_ex(pMP3, NULL, NULL, NULL); if (pcmFramesInCurrentMP3FrameIn == 0) { pSeekPoints[iSeekPoint].seekPosInBytes = mp3FrameInfo[0].bytePos; pSeekPoints[iSeekPoint].pcmFrameIndex = nextTargetPCMFrame; @@ -4349,10 +4906,10 @@ static drmp3_int16* drmp3__full_read_and_close_s16(drmp3* pMP3, drmp3_config* pC } #endif -DRMP3_API float* drmp3_open_and_read_pcm_frames_f32(drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks) +DRMP3_API float* drmp3_open_and_read_pcm_frames_f32(drmp3_read_proc onRead, drmp3_seek_proc onSeek, drmp3_tell_proc onTell, void* pUserData, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks) { drmp3 mp3; - if (!drmp3_init(&mp3, onRead, onSeek, pUserData, pAllocationCallbacks)) { + if (!drmp3_init(&mp3, onRead, onSeek, onTell, NULL, pUserData, pAllocationCallbacks)) { return NULL; } @@ -4360,10 +4917,10 @@ DRMP3_API float* drmp3_open_and_read_pcm_frames_f32(drmp3_read_proc onRead, drmp } #ifndef DR_MP3_NO_S16 -DRMP3_API drmp3_int16* drmp3_open_and_read_pcm_frames_s16(drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks) +DRMP3_API drmp3_int16* drmp3_open_and_read_pcm_frames_s16(drmp3_read_proc onRead, drmp3_seek_proc onSeek, drmp3_tell_proc onTell, void* pUserData, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks) { drmp3 mp3; - if (!drmp3_init(&mp3, onRead, onSeek, pUserData, pAllocationCallbacks)) { + if (!drmp3_init(&mp3, onRead, onSeek, onTell, NULL, pUserData, pAllocationCallbacks)) { return NULL; } @@ -4454,74 +5011,19 @@ DIFFERENCES BETWEEN minimp3 AND dr_mp3 using minimp3 in conjunction with stb_vorbis. dr_mp3 addresses this. */ -/* -RELEASE NOTES - v0.5.0 -======================= -Version 0.5.0 has breaking API changes. - -Improved Client-Defined Memory Allocation ------------------------------------------ -The main change with this release is the addition of a more flexible way of implementing custom memory allocation routines. The -existing system of DRMP3_MALLOC, DRMP3_REALLOC and DRMP3_FREE are still in place and will be used by default when no custom -allocation callbacks are specified. - -To use the new system, you pass in a pointer to a drmp3_allocation_callbacks object to drmp3_init() and family, like this: - - void* my_malloc(size_t sz, void* pUserData) - { - return malloc(sz); - } - void* my_realloc(void* p, size_t sz, void* pUserData) - { - return realloc(p, sz); - } - void my_free(void* p, void* pUserData) - { - free(p); - } - - ... - - drmp3_allocation_callbacks allocationCallbacks; - allocationCallbacks.pUserData = &myData; - allocationCallbacks.onMalloc = my_malloc; - allocationCallbacks.onRealloc = my_realloc; - allocationCallbacks.onFree = my_free; - drmp3_init_file(&mp3, "my_file.mp3", NULL, &allocationCallbacks); - -The advantage of this new system is that it allows you to specify user data which will be passed in to the allocation routines. - -Passing in null for the allocation callbacks object will cause dr_mp3 to use defaults which is the same as DRMP3_MALLOC, -DRMP3_REALLOC and DRMP3_FREE and the equivalent of how it worked in previous versions. - -Every API that opens a drmp3 object now takes this extra parameter. These include the following: - - drmp3_init() - drmp3_init_file() - drmp3_init_memory() - drmp3_open_and_read_pcm_frames_f32() - drmp3_open_and_read_pcm_frames_s16() - drmp3_open_memory_and_read_pcm_frames_f32() - drmp3_open_memory_and_read_pcm_frames_s16() - drmp3_open_file_and_read_pcm_frames_f32() - drmp3_open_file_and_read_pcm_frames_s16() - -Renamed APIs ------------- -The following APIs have been renamed for consistency with other dr_* libraries and to make it clear that they return PCM frame -counts rather than sample counts. - - drmp3_open_and_read_f32() -> drmp3_open_and_read_pcm_frames_f32() - drmp3_open_and_read_s16() -> drmp3_open_and_read_pcm_frames_s16() - drmp3_open_memory_and_read_f32() -> drmp3_open_memory_and_read_pcm_frames_f32() - drmp3_open_memory_and_read_s16() -> drmp3_open_memory_and_read_pcm_frames_s16() - drmp3_open_file_and_read_f32() -> drmp3_open_file_and_read_pcm_frames_f32() - drmp3_open_file_and_read_s16() -> drmp3_open_file_and_read_pcm_frames_s16() -*/ - /* REVISION HISTORY ================ +v0.7.0 - TBD + - The old `DRMP3_IMPLEMENTATION` has been removed. Use `DR_MP3_IMPLEMENTATION` instead. The reason for this change is that in the future everything will eventually be using the underscored naming convention in the future, so `drmp3` will become `dr_mp3`. + - API CHANGE: Add drmp3_seek_origin_end as a seek origin for the seek callback. This is required for detection of ID3v1 and APE tags. + - API CHANGE: Add onTell callback to `drmp3_init()`. This is needed in order to track the location of ID3v1 and APE tags. + - API CHANGE: Add onMeta callback to `drmp3_init()`. This is used for reporting tag data back to the caller. Currently this only reports the raw tag data which means applications need to parse the data themselves. + - API CHANGE: Rename `drmp3dec_frame_info.hz` to `drmp3dec_frame_info.sample_rate`. + - Add detection of ID3v2, ID3v1, APE and Xing/VBRI tags. This should fix errors with some files where the decoder was reading tags as audio data. + - Delay and padding samples from LAME tags are now handled. + - Fix compilation for AIX OS. + v0.6.40 - 2024-12-17 - Improve detection of ARM64EC From 1b6167b2276aeb006c7ffa033e96002097100450 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Noel?= Date: Tue, 22 Jul 2025 21:46:17 +0200 Subject: [PATCH 532/606] Add a new quirk 'SDL12COMPAT_NO_UNLOAD', usable/needed by SC3U --- src/SDL12_compat.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 1436fc40c..1c30e521d 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1433,6 +1433,9 @@ static QuirkEntryType quirks[] = { /* The 32-bit Steam build only of Multiwinia Quits but doesn't re-Init */ {"multiwinia.bin.x86", "SDL12COMPAT_NO_QUIT_VIDEO", "1"}, + /* SimCity 3000 tries to call SDL_DestroyMutex after we have been unloaded */ + {"sc3u.dynamic", "SDL12COMPAT_NO_UNLOAD", "1"}, + /* Loki Unreal Tournament '99 runs at hyperspeed if the framerate is too high. Force it to vsync. You should use the newer OldUnreal binaries with SDL2 instead! */ {"ut-bin", "SDL12COMPAT_SYNC_TO_VBLANK", "1"} #else @@ -1784,7 +1787,9 @@ static void dllinit(void) static void dllquit(void) __attribute__((destructor)); static void dllquit(void) { - UnloadSDL20(); + if (!SDL12Compat_GetHintBoolean("SDL12COMPAT_NO_UNLOAD", SDL_FALSE)) { + UnloadSDL20(); + } } #elif defined(_WIN32) && (defined(_MSC_VER) || defined(__MINGW32__) || defined(__WATCOMC__)) From 3547d7a189f852641768b217d988484b56a37fc5 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Wed, 23 Jul 2025 11:56:50 +0300 Subject: [PATCH 533/606] update to latest dr_mp3.h from mainstream --- src/SDL12_compat.c | 9 ++--- src/dr_mp3.h | 96 +++++++++++++++++++++++----------------------- 2 files changed, 51 insertions(+), 54 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 1c30e521d..02b787e22 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -8882,15 +8882,15 @@ mp3_sdlrwops_read(void *data, void *buf, size_t bytesToRead) static drmp3_bool32 mp3_sdlrwops_seek(void *data, int offset, drmp3_seek_origin origin) { - int whence = (origin == drmp3_seek_origin_start) ? RW_SEEK_SET : RW_SEEK_CUR; + int whence; switch (origin) { - case drmp3_seek_origin_start: + case DRMP3_SEEK_SET: whence = RW_SEEK_SET; break; - case drmp3_seek_origin_current: + case DRMP3_SEEK_CUR: whence = RW_SEEK_CUR; break; - case drmp3_seek_origin_end: + case DRMP3_SEEK_END: whence = RW_SEEK_END; break; default: @@ -8906,7 +8906,6 @@ mp3_sdlrwops_tell(void *data, drmp3_int64 *pos) return (*pos != -1) ? DRMP3_TRUE : DRMP3_FALSE; } - static SDL_bool OpenSDL2AudioDevice(SDL_AudioSpec *want); static int CloseSDL2AudioDevice(void); static SDL_bool ResetAudioStream(SDL_AudioStream **_stream, SDL_AudioSpec *spec, const SDL_AudioSpec *to, const SDL_AudioFormat fromfmt, const Uint8 fromchannels, const int fromfreq); diff --git a/src/dr_mp3.h b/src/dr_mp3.h index e5c9aee67..b2bc1fc92 100644 --- a/src/dr_mp3.h +++ b/src/dr_mp3.h @@ -1,6 +1,6 @@ /* MP3 audio decoder. Choice of public domain or MIT-0. See license statements at the end of this file. -dr_mp3 - v0.7.0 - TBD +dr_mp3 - v0.7.0 - 2025-07-23 David Reid - mackron@gmail.com @@ -293,9 +293,9 @@ Main API (Pull API) */ typedef enum { - drmp3_seek_origin_start, - drmp3_seek_origin_current, - drmp3_seek_origin_end + DRMP3_SEEK_SET, + DRMP3_SEEK_CUR, + DRMP3_SEEK_END } drmp3_seek_origin; typedef struct @@ -2676,13 +2676,13 @@ static size_t drmp3__on_read_clamped(drmp3* pMP3, void* pBufferOut, size_t bytes static drmp3_bool32 drmp3__on_seek(drmp3* pMP3, int offset, drmp3_seek_origin origin) { DRMP3_ASSERT(offset >= 0); - DRMP3_ASSERT(origin == drmp3_seek_origin_start || origin == drmp3_seek_origin_current); + DRMP3_ASSERT(origin == DRMP3_SEEK_SET || origin == DRMP3_SEEK_CUR); if (!pMP3->onSeek(pMP3->pUserData, offset, origin)) { return DRMP3_FALSE; } - if (origin == drmp3_seek_origin_start) { + if (origin == DRMP3_SEEK_SET) { pMP3->streamCursor = (drmp3_uint64)offset; } else{ pMP3->streamCursor += offset; @@ -2698,19 +2698,19 @@ static drmp3_bool32 drmp3__on_seek_64(drmp3* pMP3, drmp3_uint64 offset, drmp3_se } /* Getting here "offset" is too large for a 32-bit integer. We just keep seeking forward until we hit the offset. */ - if (!drmp3__on_seek(pMP3, 0x7FFFFFFF, drmp3_seek_origin_start)) { + if (!drmp3__on_seek(pMP3, 0x7FFFFFFF, DRMP3_SEEK_SET)) { return DRMP3_FALSE; } offset -= 0x7FFFFFFF; while (offset > 0) { if (offset <= 0x7FFFFFFF) { - if (!drmp3__on_seek(pMP3, (int)offset, drmp3_seek_origin_current)) { + if (!drmp3__on_seek(pMP3, (int)offset, DRMP3_SEEK_CUR)) { return DRMP3_FALSE; } offset = 0; } else { - if (!drmp3__on_seek(pMP3, 0x7FFFFFFF, drmp3_seek_origin_current)) { + if (!drmp3__on_seek(pMP3, 0x7FFFFFFF, DRMP3_SEEK_CUR)) { return DRMP3_FALSE; } offset -= 0x7FFFFFFF; @@ -2977,7 +2977,7 @@ static drmp3_bool32 drmp3_init_internal(drmp3* pMP3, drmp3_read_proc onRead, drm /* We'll first check for any ID3v1 or APE tags. */ #if 1 if (onSeek != NULL && onTell != NULL) { - if (onSeek(pUserData, 0, drmp3_seek_origin_end)) { + if (onSeek(pUserData, 0, DRMP3_SEEK_END)) { drmp3_int64 streamLen; int streamEndOffset = 0; @@ -2986,7 +2986,7 @@ static drmp3_bool32 drmp3_init_internal(drmp3* pMP3, drmp3_read_proc onRead, drm /* ID3v1 */ if (streamLen > 128) { char id3[3]; - if (onSeek(pUserData, streamEndOffset - 128, drmp3_seek_origin_end)) { + if (onSeek(pUserData, streamEndOffset - 128, DRMP3_SEEK_END)) { if (onRead(pUserData, id3, 3) == 3 && id3[0] == 'T' && id3[1] == 'A' && id3[2] == 'G') { /* We have an ID3v1 tag. */ streamEndOffset -= 128; @@ -3014,7 +3014,7 @@ static drmp3_bool32 drmp3_init_internal(drmp3* pMP3, drmp3_read_proc onRead, drm /* APE */ if (streamLen > 32) { char ape[32]; /* The footer. */ - if (onSeek(pUserData, streamEndOffset - 32, drmp3_seek_origin_end)) { + if (onSeek(pUserData, streamEndOffset - 32, DRMP3_SEEK_END)) { if (onRead(pUserData, ape, 32) == 32 && ape[0] == 'A' && ape[1] == 'P' && ape[2] == 'E' && ape[3] == 'T' && ape[4] == 'A' && ape[5] == 'G' && ape[6] == 'E' && ape[7] == 'X') { /* We have an APE tag. */ drmp3_uint32 tagSize = @@ -3029,7 +3029,7 @@ static drmp3_bool32 drmp3_init_internal(drmp3* pMP3, drmp3_read_proc onRead, drm /* Fire a metadata callback for the APE data. Must include both the main content and footer. */ if (onMeta != NULL) { /* We first need to seek to the start of the APE tag. */ - if (onSeek(pUserData, streamEndOffset, drmp3_seek_origin_end)) { + if (onSeek(pUserData, streamEndOffset, DRMP3_SEEK_END)) { size_t apeTagSize = (size_t)tagSize + 32; drmp3_uint8* pTagData = (drmp3_uint8*)drmp3_malloc(apeTagSize, pAllocationCallbacks); if (pTagData != NULL) { @@ -3048,7 +3048,7 @@ static drmp3_bool32 drmp3_init_internal(drmp3* pMP3, drmp3_read_proc onRead, drm } /* Seek back to the start. */ - if (!onSeek(pUserData, 0, drmp3_seek_origin_start)) { + if (!onSeek(pUserData, 0, DRMP3_SEEK_SET)) { return DRMP3_FALSE; /* Failed to seek back to the start. */ } @@ -3059,7 +3059,7 @@ static drmp3_bool32 drmp3_init_internal(drmp3* pMP3, drmp3_read_proc onRead, drm } } else { /* Failed to get the length of the stream. ID3v1 and APE tags cannot be skipped. */ - if (!onSeek(pUserData, 0, drmp3_seek_origin_start)) { + if (!onSeek(pUserData, 0, DRMP3_SEEK_SET)) { return DRMP3_FALSE; /* Failed to seek back to the start. */ } } @@ -3105,7 +3105,7 @@ static drmp3_bool32 drmp3_init_internal(drmp3* pMP3, drmp3_read_proc onRead, drm } else { /* Don't have a metadata callback, so just skip the tag. */ if (onSeek != NULL) { - if (!onSeek(pUserData, tagSize, drmp3_seek_origin_current)) { + if (!onSeek(pUserData, tagSize, DRMP3_SEEK_CUR)) { return DRMP3_FALSE; /* Failed to seek past the ID3v2 tag. */ } } else { @@ -3132,7 +3132,7 @@ static drmp3_bool32 drmp3_init_internal(drmp3* pMP3, drmp3_read_proc onRead, drm } else { /* Not an ID3v2 tag. Seek back to the start. */ if (onSeek != NULL) { - if (!onSeek(pUserData, 0, drmp3_seek_origin_start)) { + if (!onSeek(pUserData, 0, DRMP3_SEEK_SET)) { return DRMP3_FALSE; /* Failed to seek back to the start. */ } } else { @@ -3321,40 +3321,34 @@ static size_t drmp3__on_read_memory(void* pUserData, void* pBufferOut, size_t by static drmp3_bool32 drmp3__on_seek_memory(void* pUserData, int byteOffset, drmp3_seek_origin origin) { drmp3* pMP3 = (drmp3*)pUserData; + drmp3_int64 newCursor; DRMP3_ASSERT(pMP3 != NULL); - if (origin == drmp3_seek_origin_current) { - if (byteOffset > 0) { - if (pMP3->memory.currentReadPos + byteOffset > pMP3->memory.dataSize) { - return DRMP3_FALSE; /* Trying to seek too far forward. */ - } - } else { - if (pMP3->memory.currentReadPos < (size_t)-byteOffset) { - return DRMP3_FALSE; /* Trying to seek too far backwards. */ - } - } + newCursor = pMP3->memory.currentReadPos; - /* This will never underflow thanks to the clamps above. */ - pMP3->memory.currentReadPos += byteOffset; - } else if (origin == drmp3_seek_origin_start) { - if ((drmp3_uint32)byteOffset <= pMP3->memory.dataSize) { - pMP3->memory.currentReadPos = byteOffset; - } else { - return DRMP3_FALSE; /* Trying to seek too far forward. */ - } - } else if (origin == drmp3_seek_origin_end) { - if (byteOffset > 0) { - return DRMP3_FALSE; /* Trying to seek beyond the end of the buffer. */ - } + if (origin == DRMP3_SEEK_SET) { + newCursor = 0; + } else if (origin == DRMP3_SEEK_CUR) { + newCursor = (drmp3_int64)pMP3->memory.currentReadPos; + } else if (origin == DRMP3_SEEK_END) { + newCursor = (drmp3_int64)pMP3->memory.dataSize; + } else { + DRMP3_ASSERT(!"Invalid seek origin"); + return DRMP3_FALSE; + } - if ((size_t)(-byteOffset) > pMP3->memory.dataSize) { - return DRMP3_FALSE; /* Trying to seek too far back. */ - } + newCursor += byteOffset; - pMP3->memory.currentReadPos = pMP3->memory.dataSize - (size_t)(-byteOffset); + if (newCursor < 0) { + return DRMP3_FALSE; /* Trying to seek prior to the start of the buffer. */ + } + if ((size_t)newCursor > pMP3->memory.dataSize) { + return DRMP3_FALSE; /* Trying to seek beyond the end of the buffer. */ } + pMP3->memory.currentReadPos = (size_t)newCursor; + return DRMP3_TRUE; } @@ -3987,9 +3981,9 @@ static size_t drmp3__on_read_stdio(void* pUserData, void* pBufferOut, size_t byt static drmp3_bool32 drmp3__on_seek_stdio(void* pUserData, int offset, drmp3_seek_origin origin) { int whence = SEEK_SET; - if (origin == drmp3_seek_origin_current) { + if (origin == DRMP3_SEEK_CUR) { whence = SEEK_CUR; - } else if (origin == drmp3_seek_origin_end) { + } else if (origin == DRMP3_SEEK_END) { whence = SEEK_END; } @@ -4330,7 +4324,7 @@ static drmp3_bool32 drmp3_seek_to_start_of_stream(drmp3* pMP3) DRMP3_ASSERT(pMP3->onSeek != NULL); /* Seek to the start of the stream to begin with. */ - if (!drmp3__on_seek_64(pMP3, pMP3->streamStartOffset, drmp3_seek_origin_start)) { + if (!drmp3__on_seek_64(pMP3, pMP3->streamStartOffset, DRMP3_SEEK_SET)) { return DRMP3_FALSE; } @@ -4430,7 +4424,7 @@ static drmp3_bool32 drmp3_seek_to_pcm_frame__seek_table(drmp3* pMP3, drmp3_uint6 } /* First thing to do is seek to the first byte of the relevant MP3 frame. */ - if (!drmp3__on_seek_64(pMP3, seekPoint.seekPosInBytes, drmp3_seek_origin_start)) { + if (!drmp3__on_seek_64(pMP3, seekPoint.seekPosInBytes, DRMP3_SEEK_SET)) { return DRMP3_FALSE; /* Failed to seek. */ } @@ -5014,9 +5008,13 @@ DIFFERENCES BETWEEN minimp3 AND dr_mp3 /* REVISION HISTORY ================ -v0.7.0 - TBD +v0.7.0 - 2025-07-23 - The old `DRMP3_IMPLEMENTATION` has been removed. Use `DR_MP3_IMPLEMENTATION` instead. The reason for this change is that in the future everything will eventually be using the underscored naming convention in the future, so `drmp3` will become `dr_mp3`. - - API CHANGE: Add drmp3_seek_origin_end as a seek origin for the seek callback. This is required for detection of ID3v1 and APE tags. + - API CHANGE: Seek origins have been renamed to match the naming convention used by dr_wav and my other libraries. + - drmp3_seek_origin_start -> DRMP3_SEEK_SET + - drmp3_seek_origin_current -> DRMP3_SEEK_CUR + - DRMP3_SEEK_END (new) + - API CHANGE: Add DRMP3_SEEK_END as a seek origin for the seek callback. This is required for detection of ID3v1 and APE tags. - API CHANGE: Add onTell callback to `drmp3_init()`. This is needed in order to track the location of ID3v1 and APE tags. - API CHANGE: Add onMeta callback to `drmp3_init()`. This is used for reporting tag data back to the caller. Currently this only reports the raw tag data which means applications need to parse the data themselves. - API CHANGE: Rename `drmp3dec_frame_info.hz` to `drmp3dec_frame_info.sample_rate`. From 678ad7e7382f87fb57648e25d2204e5b4e2b5b40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Noel?= Date: Wed, 23 Jul 2025 15:51:39 +0200 Subject: [PATCH 534/606] Add a new quirk 'SDL12COMPAT_MAX_FPS' for SoldierOfFortune & UT99 --- src/SDL12_compat.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 02b787e22..c89f3f109 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1018,6 +1018,8 @@ static SDL12_EventFilter EventFilter12 = NULL; static SDL12_Cursor *CurrentCursor12 = NULL; static Uint8 EventStates[SDL12_NUMEVENTS]; static int SwapInterval = 0; +static float OpenGLBuffersSwapTickInterval = 0.f; +static Uint32 OpenGLBuffersLastSwapTicks = 0; static SDL_bool JoysticksAreGameControllers = SDL_FALSE; static SDL12_Joystick *JoystickList = NULL; static int NumJoysticks = 0; @@ -1436,8 +1438,13 @@ static QuirkEntryType quirks[] = { /* SimCity 3000 tries to call SDL_DestroyMutex after we have been unloaded */ {"sc3u.dynamic", "SDL12COMPAT_NO_UNLOAD", "1"}, + /* Loki Soldier of Fortune - Sliding/ice-skating when moving if framerate is too high */ + {"sof-bin", "SDL12COMPAT_SYNC_TO_VBLANK", "1"}, + {"sof-bin", "SDL12COMPAT_MAX_FPS", "120"}, + /* Loki Unreal Tournament '99 runs at hyperspeed if the framerate is too high. Force it to vsync. You should use the newer OldUnreal binaries with SDL2 instead! */ - {"ut-bin", "SDL12COMPAT_SYNC_TO_VBLANK", "1"} + {"ut-bin", "SDL12COMPAT_SYNC_TO_VBLANK", "1"}, + {"ut-bin", "SDL12COMPAT_MAX_FPS", "120"} #else /* TODO: Add any quirks needed for this system. */ @@ -6235,6 +6242,7 @@ SetVideoModeImpl(int width, int height, int bpp, Uint32 flags12) int scaled_width = width; int scaled_height = height; const char *fromwin_env = NULL; + int gl_max_fps; VideoSurface12 = &VideoSurface12Location; @@ -6260,6 +6268,12 @@ SetVideoModeImpl(int width, int height, int bpp, Uint32 flags12) the resolution in some or all parts of their code.) Because OpenGL scaling is never used for windows, it is always false there. */ use_highdpi = (flags12 & SDL12_FULLSCREEN) ? use_gl_scaling : SDL_FALSE; + + gl_max_fps = SDL12Compat_GetHintInt("SDL12COMPAT_MAX_FPS", 0); + if(gl_max_fps != 0) { + OpenGLBuffersSwapTickInterval = 1000.f / gl_max_fps; + OpenGLBuffersLastSwapTicks = SDL20_GetTicks(); + } } use_highdpi = SDL12Compat_GetHintBoolean("SDL12COMPAT_HIGHDPI", use_highdpi); @@ -8162,6 +8176,12 @@ DECLSPEC12 void SDLCALL SDL_GL_SwapBuffers(void) { if (VideoWindow20) { + if(OpenGLBuffersSwapTickInterval != 0.f) { + const Uint32 tickDelta = SDL20_GetTicks() - OpenGLBuffersLastSwapTicks; + if(tickDelta < OpenGLBuffersSwapTickInterval) { + SDL20_Delay( ((int)OpenGLBuffersSwapTickInterval+0.5) - tickDelta ); + } + } /* Some applications, e.g. Awesomenauts, play with glXMakeCurrent() behind our backs and break SwapBuffers() */ if (ForceGLSwapBufferContext) { SDL20_GL_MakeCurrent(VideoWindow20, VideoGLContext20); @@ -8211,6 +8231,10 @@ SDL_GL_SwapBuffers(void) } else { SDL20_GL_SwapWindow(VideoWindow20); } + + if(OpenGLBuffersSwapTickInterval != 0.f) { + OpenGLBuffersLastSwapTicks = SDL20_GetTicks(); + } } } From f14ede5a8bc8384ab771aca61a71ba951c70e038 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Thu, 24 Jul 2025 20:00:04 +0300 Subject: [PATCH 535/606] fix bad parenthesing leading to MSVC C4244 warning after commit 678ad7e --- src/SDL12_compat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index c89f3f109..53ef8da43 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -8179,7 +8179,7 @@ SDL_GL_SwapBuffers(void) if(OpenGLBuffersSwapTickInterval != 0.f) { const Uint32 tickDelta = SDL20_GetTicks() - OpenGLBuffersLastSwapTicks; if(tickDelta < OpenGLBuffersSwapTickInterval) { - SDL20_Delay( ((int)OpenGLBuffersSwapTickInterval+0.5) - tickDelta ); + SDL20_Delay((int)(OpenGLBuffersSwapTickInterval + 0.5f) - tickDelta); } } /* Some applications, e.g. Awesomenauts, play with glXMakeCurrent() behind our backs and break SwapBuffers() */ From c0f7938e368fd2f5b87f04f43b8468f251e6e48a Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Fri, 25 Jul 2025 00:23:50 +0300 Subject: [PATCH 536/606] update to latest dr_mp3.h from mainstream --- src/dr_mp3.h | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/dr_mp3.h b/src/dr_mp3.h index b2bc1fc92..beeac70b9 100644 --- a/src/dr_mp3.h +++ b/src/dr_mp3.h @@ -1,6 +1,6 @@ /* MP3 audio decoder. Choice of public domain or MIT-0. See license statements at the end of this file. -dr_mp3 - v0.7.0 - 2025-07-23 +dr_mp3 - v0.7.1 - TBD David Reid - mackron@gmail.com @@ -78,7 +78,7 @@ extern "C" { #define DRMP3_VERSION_MAJOR 0 #define DRMP3_VERSION_MINOR 7 -#define DRMP3_VERSION_REVISION 0 +#define DRMP3_VERSION_REVISION 1 #define DRMP3_VERSION_STRING DRMP3_XSTRINGIFY(DRMP3_VERSION_MAJOR) "." DRMP3_XSTRINGIFY(DRMP3_VERSION_MINOR) "." DRMP3_XSTRINGIFY(DRMP3_VERSION_REVISION) #include /* For size_t. */ @@ -1244,6 +1244,14 @@ static float drmp3_L3_ldexp_q2(float y, int exp_q2) return y; } +/* +I've had reports of GCC 14 throwing an incorrect -Wstringop-overflow warning here. This is an attempt +to silence this warning. +*/ +#if (defined(__GNUC__) && (__GNUC__ >= 14)) && !defined(__clang__) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wstringop-overflow" +#endif static void drmp3_L3_decode_scalefactors(const drmp3_uint8 *hdr, drmp3_uint8 *ist_pos, drmp3_bs *bs, const drmp3_L3_gr_info *gr, float *scf, int ch) { static const drmp3_uint8 g_scf_partitions[3][28] = { @@ -1305,6 +1313,9 @@ static void drmp3_L3_decode_scalefactors(const drmp3_uint8 *hdr, drmp3_uint8 *is scf[i] = drmp3_L3_ldexp_q2(gain, iscf[i] << scf_shift); } } +#if (defined(__GNUC__) && (__GNUC__ >= 14)) && !defined(__clang__) + #pragma GCC diagnostic pop +#endif static const float g_drmp3_pow43[129 + 16] = { 0,-1,-2.519842f,-4.326749f,-6.349604f,-8.549880f,-10.902724f,-13.390518f,-16.000000f,-18.720754f,-21.544347f,-24.463781f,-27.473142f,-30.567351f,-33.741992f,-36.993181f, @@ -5008,6 +5019,9 @@ DIFFERENCES BETWEEN minimp3 AND dr_mp3 /* REVISION HISTORY ================ +v0.7.1 - TBD + - Silence a warning with GCC. + v0.7.0 - 2025-07-23 - The old `DRMP3_IMPLEMENTATION` has been removed. Use `DR_MP3_IMPLEMENTATION` instead. The reason for this change is that in the future everything will eventually be using the underscored naming convention in the future, so `drmp3` will become `dr_mp3`. - API CHANGE: Seek origins have been renamed to match the naming convention used by dr_wav and my other libraries. From 44b1e1f234465248ee7e04562e67d452d63714a8 Mon Sep 17 00:00:00 2001 From: David Gow Date: Tue, 29 Jul 2025 16:14:19 +0800 Subject: [PATCH 537/606] SDL_CreateRGBSurface: Don't assert SDL_PREALLOC not set on 0-sized surface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SDL_CreateRGBSurface currently asserts that SDL_PREALLOC is not set. However, if the surface is empty (width or height are zero), then it doesn't matter if pixels is valid. SDL2 does allocate an "empty" pixels, and so doesn't set SDL_PREALLOCATED, but SDL3 (including via sdl2compat) doesn't, leaving the empty SDL_Surface with SDL_PREALLOCATED (so it doesn't try to free the NULL pointer). This _could_ be worked around in sdl2compat, but the SDL3/sdl2compat behaviour does make sense, and it's only the zealous assertion here which breaks. Civilization: Call To Power triggers this by trying to create a bunch of 0×0 surfaces at startup, and is fixed by this patch. Fixes: 13efe605cc42 ("Factor out enough of SDL_CreateRGBSurface to create surfaces in-place") --- src/SDL12_compat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 53ef8da43..1d309a2e6 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -5487,7 +5487,7 @@ SDL_CreateRGBSurface(Uint32 flags12, int width, int height, int depth, Uint32 Rm return NULL; } - SDL_assert((surface12->flags & ~(SDL12_SRCCOLORKEY|SDL12_SRCALPHA)) == 0); /* shouldn't have prealloc, rleaccel, or dontfree. */ + SDL_assert(!(width && height) || ((surface12->flags & ~(SDL12_SRCCOLORKEY|SDL12_SRCALPHA))) == 0); /* shouldn't have prealloc, rleaccel, or dontfree. */ Surface12SetMasks(surface12, Rmask, Gmask, Bmask, Amask); return surface12; } From f8d5665e2cb84562447374b6a12139acac2ee2ff Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Thu, 31 Jul 2025 01:32:02 +0300 Subject: [PATCH 538/606] avoid unused function warnings in non-linux builds --- src/SDL12_compat.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 1d309a2e6..2dda77845 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1071,6 +1071,7 @@ SDL20_atoi(const char *str) return SDL20_strtol(str, NULL, 10); } +#ifdef __linux__ /* you can use SDL20_atoi once we're past startup. */ static int SDL12COMPAT_atoi(const char *str) @@ -1109,6 +1110,7 @@ SDL12COMPAT_atoi(const char *str) return (retval + (((int) (*ptr - '0')) * multiplier)) * signmult; } +#endif /* __linux__ */ static char * SDL12COMPAT_stpcpy(char *dst, const char *src) From 032c8b8409a6aaaf6cc4bca6d7c3010f28dd8da2 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Thu, 31 Jul 2025 01:32:28 +0300 Subject: [PATCH 539/606] mac: replace @autoreleasepool use with NSAutoreleasePool Better gcc comatibility this way. asm output from clang-8 is identical. --- src/SDL12_compat_objc.m | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/SDL12_compat_objc.m b/src/SDL12_compat_objc.m index 31f0ec8f2..ab7b56eec 100644 --- a/src/SDL12_compat_objc.m +++ b/src/SDL12_compat_objc.m @@ -66,7 +66,7 @@ SDL12_PRIVATE void error_dialog(const char *errorMsg) SDL12_PRIVATE void SDL12COMPAT_NSLog(const char *prefix, const char *text) { - @autoreleasepool { + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; { NSString *nsText = [NSString stringWithUTF8String:text]; if (prefix && *prefix) { NSString *nsPrefix = [NSString stringWithUTF8String:prefix]; @@ -75,6 +75,7 @@ SDL12_PRIVATE void SDL12COMPAT_NSLog(const char *prefix, const char *text) NSLog(@"%@", nsText); } } + [pool drain]; } #endif From 3a9149a3e099b98de5902324adf5d82ce14be35e Mon Sep 17 00:00:00 2001 From: David Gow Date: Thu, 31 Jul 2025 22:08:34 +0800 Subject: [PATCH 540/606] Hint: Add SDL12COMPAT_WINDOWED_MODE_LIST hint, to make SDL_ListModes() work in windowed mode. (#363) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a new boolean hint, which makes SDL_ListModes() always return a mode list, even if the flags passed in are for windowed mode. By default, we return -1 in this case, to indicate that any mode is supported. However, some older titles pass 0 for flags here even if they're intending to run in fullscreen, and if -1 is returned, attempt to populate their own mode list (and select a mode) themselves. For example, Civilization: Call To Power will add the current desktop mode (if it can glean it from X11, which doesn't work on Wayland, and gives an unusuable combined size for multi-monitor setups even on X11), along with the hardcoded list of 1024×768, 800×600, and 640×480). By always returning sdl12-compat's list of modes (some of which may be "fake"), we get a much more modern list of supported modes, which allows the game to comfortably run at higher resolutions. --- README.md | 9 +++++++++ src/SDL12_compat.c | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 58cd6f8d1..9f463787f 100644 --- a/README.md +++ b/README.md @@ -274,6 +274,15 @@ The available options are: video subsystem. This works around buggy applications which try to use the video subsystem after shutting it down. +- SDL12COMPAT_WINDOWED_MODE_LIST: (checked during SDL_ListModes) + If enabled, returns the list of available video modes in SDL_ListModes(), + even if the flags provided do not include SDL_FULLSCREEN. Otherwise + (by default), it will return -1 to tell the application that all modes + are available. This may cause some applications to fall back to an internal + list, which may not be as exhaustive as the one sdl12-compat provides. + Try this if a game is not listing all of the screen resolutions it should + support. + # Compatibility issues with OpenGL scaling diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 2dda77845..7cc2b47b0 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -5662,6 +5662,7 @@ SDL_ListModes(const SDL12_PixelFormat *format12, Uint32 flags) VideoModeList *best_modes = NULL; Uint32 bpp; int i; + SDL_bool windowed_mode_list = SDL12Compat_GetHintBoolean("SDL12COMPAT_WINDOWED_MODE_LIST", SDL_FALSE); if (!SDL20_WasInit(SDL_INIT_VIDEO)) { SDL20_SetError("Video subsystem not initialized"); @@ -5677,7 +5678,7 @@ SDL_ListModes(const SDL12_PixelFormat *format12, Uint32 flags) return (SDL12_Rect **) -1; /* 1.2's dummy driver always returns -1, and it's useful to special-case that. */ } - if (!(flags & SDL12_FULLSCREEN)) { + if (!(flags & SDL12_FULLSCREEN) && !windowed_mode_list) { return (SDL12_Rect **) -1; /* any resolution is fine. */ } From 25ce0ef03eece1a7a099483afc33cb5ed3fc3dcc Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 7 Aug 2025 19:41:33 -0400 Subject: [PATCH 541/606] api: Added SDL_SetRefreshRate(). This was an entry point in a StepMania fork of SDL 1.2. See discussion in https://github.com/libsdl-org/SDL-1.2/pull/893 --- include/SDL/SDL_video.h | 4 ++++ src/SDL12.exports | 1 + src/SDL12_compat.c | 38 ++++++++++++++++++++++++++++++++++++-- src/SDL20_syms.h | 3 +++ test/testsprite.c | 8 +++++++- 5 files changed, 51 insertions(+), 3 deletions(-) diff --git a/include/SDL/SDL_video.h b/include/SDL/SDL_video.h index bda9e55f4..b67cbe97e 100644 --- a/include/SDL/SDL_video.h +++ b/include/SDL/SDL_video.h @@ -222,6 +222,10 @@ extern DECLSPEC int SDLCALL SDL_WM_ToggleFullScreen(SDL_Surface *surface); extern DECLSPEC SDL_GrabMode SDLCALL SDL_WM_GrabInput(SDL_GrabMode mode); extern DECLSPEC int SDLCALL SDL_SoftStretch(SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect); +/* this was never in an real SDL-1.2 release, but apparently StepMania was maintaining a fork with this API for literally years. */ +#define SDL_REFRESH_DEFAULT 0 +extern DECLSPEC void SDLCALL SDL_SetRefreshRate(int rate); + #define SDL_SWSURFACE 0x00000000 #define SDL_HWSURFACE 0x00000001 #define SDL_ASYNCBLIT 0x00000004 diff --git a/src/SDL12.exports b/src/SDL12.exports index fdca921d4..29423a462 100644 --- a/src/SDL12.exports +++ b/src/SDL12.exports @@ -193,6 +193,7 @@ ++'_SDL_GetVideoInfo'.'SDL.dll'.'SDL_GetVideoInfo'.'SDL_GetVideoInfo' ++'_SDL_ListModes'.'SDL.dll'.'SDL_ListModes'.'SDL_ListModes' ++'_SDL_VideoModeOK'.'SDL.dll'.'SDL_VideoModeOK'.'SDL_VideoModeOK' +++'_SDL_SetRefreshRate'.'SDL.dll'.'SDL_SetVideoMode'.'SDL_SetRefreshRate' ++'_SDL_SetVideoMode'.'SDL.dll'.'SDL_SetVideoMode'.'SDL_SetVideoMode' ++'_SDL_DisplayFormat'.'SDL.dll'.'SDL_DisplayFormat'.'SDL_DisplayFormat' ++'_SDL_DisplayFormatAlpha'.'SDL.dll'.'SDL_DisplayFormatAlpha'.'SDL_DisplayFormatAlpha' diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 7cc2b47b0..b3c2ec565 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -222,6 +222,8 @@ static float SDL20_truncf(float x) #define SDL12_LOGPAL 1 #define SDL12_PHYSPAL 2 +#define SDL12_REFRESH_DEFAULT 0 + #ifndef SDL_SIMD_ALIGNED #define SDL_SIMD_ALIGNED 0x00000008 #endif @@ -1060,6 +1062,8 @@ static SDL_bool AllowThreadedDraws = SDL_FALSE; static SDL_bool AllowThreadedPumps = SDL_FALSE; static SDL_bool WantCompatibilityAudioCVT = SDL_FALSE; static SDL_bool PreserveDestinationAlpha = SDL_TRUE; +static int DesiredRefreshRate = SDL12_REFRESH_DEFAULT; +static int CurrentRefreshRate = SDL12_REFRESH_DEFAULT; /* This is a KEYDOWN event which is being held for a follow-up TEXTINPUT */ static SDL12_Event PendingKeydownEvent; @@ -5885,6 +5889,8 @@ EndVidModeCreate(void) VideoSurfaceUpdatedInBackgroundThread = SDL_FALSE; SetVideoModeThread = 0; + CurrentRefreshRate = SDL12_REFRESH_DEFAULT; + return NULL; } @@ -6230,6 +6236,14 @@ UnlockVideoRenderer(void) static void HandleInputGrab(SDL12_GrabMode mode); + +/* SDL_SetRefreshRate was never in an real SDL-1.2 release, but apparently StepMania was maintaining a fork with this API for literally years. */ +DECLSPEC12 void SDLCALL +SDL_SetRefreshRate(int rate) +{ + DesiredRefreshRate = (rate >= 0) ? rate : 0; /* takes effect on next SDL_SetVideoMode call. */ +} + static SDL12_Surface * SetVideoModeImpl(int width, int height, int bpp, Uint32 flags12) { @@ -6246,7 +6260,7 @@ SetVideoModeImpl(int width, int height, int bpp, Uint32 flags12) int scaled_height = height; const char *fromwin_env = NULL; int gl_max_fps; - + SDL_bool force_display_mode = SDL_FALSE; VideoSurface12 = &VideoSurface12Location; if (flags12 & SDL12_OPENGL) { @@ -6341,6 +6355,8 @@ SetVideoModeImpl(int width, int height, int bpp, Uint32 flags12) EndVidModeCreate(); /* rebuild the window if moving to/from a GL context */ } else if (VideoSurface12->surface20 && (VideoSurface12->surface20->format->format != appfmt)) { EndVidModeCreate(); /* rebuild the window if changing pixel format */ + } else if (DesiredRefreshRate != CurrentRefreshRate) { + EndVidModeCreate(); /* rebuild the window if changing refresh rate */ } else { /* SDL 1.2 (infuriatingly!) destroys the window (and GL context!) on each resize in some cases, on various platforms. Try to match that. */ #ifdef __WINDOWS__ @@ -6392,10 +6408,13 @@ SetVideoModeImpl(int width, int height, int bpp, Uint32 flags12) GPU, so use FULLSCREEN_DESKTOP and logical scaling there. If possible, we'll do this with OpenGL, too, but we might not be able to. */ - if (use_gl_scaling || ((flags12 & SDL12_OPENGL) == 0) || ((dmode.w == width) && (dmode.h == height))) { + if ((use_gl_scaling || ((flags12 & SDL12_OPENGL) == 0) || ((dmode.w == width) && (dmode.h == height))) && (DesiredRefreshRate == SDL12_REFRESH_DEFAULT)) { fullscreen_flags20 |= SDL_WINDOW_FULLSCREEN_DESKTOP; } else { fullscreen_flags20 |= SDL_WINDOW_FULLSCREEN; + if (DesiredRefreshRate != SDL12_REFRESH_DEFAULT) { + force_display_mode = SDL_TRUE; + } } } else if (fix_bordless_fs_win && (flags12 & SDL12_NOFRAME) && (width == dmode.w) && (height == dmode.h)) { /* app appears to be trying to do a "borderless fullscreen windowed" mode, so just bump @@ -6459,6 +6478,21 @@ SetVideoModeImpl(int width, int height, int bpp, Uint32 flags12) if (VideoIcon20) { SDL20_SetWindowIcon(VideoWindow20, VideoIcon20); } + + if (force_display_mode) { + SDL_DisplayMode desired_mode, closest_mode; + SDL20_zero(desired_mode); + SDL20_zero(closest_mode); + desired_mode.w = scaled_width; + desired_mode.h = scaled_height; + desired_mode.refresh_rate = DesiredRefreshRate; + if (!SDL20_GetClosestDisplayMode(SDL20_GetWindowDisplayIndex(VideoWindow20), &desired_mode, &closest_mode)) { + return EndVidModeCreate(); + } else if (SDL20_SetWindowDisplayMode(VideoWindow20, &closest_mode) < 0) { + return EndVidModeCreate(); + } + CurrentRefreshRate = DesiredRefreshRate; + } } else { /* resize it */ SDL20_SetWindowSize(VideoWindow20, scaled_width, scaled_height); SDL20_SetWindowFullscreen(VideoWindow20, fullscreen_flags20); diff --git a/src/SDL20_syms.h b/src/SDL20_syms.h index 3d68a94e3..36af4bca7 100644 --- a/src/SDL20_syms.h +++ b/src/SDL20_syms.h @@ -80,6 +80,9 @@ SDL20_SYM(int,GetDisplayMode,(int a, int b, SDL_DisplayMode *c),(a,b,c),return) SDL20_SYM(int,GetDesktopDisplayMode,(int a, SDL_DisplayMode *b),(a,b),return) SDL20_SYM(int,GetCurrentDisplayMode,(int a, SDL_DisplayMode *b),(a,b),return) SDL20_SYM(int,GetWindowDisplayMode,(SDL_Window *a, SDL_DisplayMode *b),(a,b),return) +SDL20_SYM(SDL_DisplayMode *,GetClosestDisplayMode,(int a, const SDL_DisplayMode *b, SDL_DisplayMode *c),(a,b,c),return) +SDL20_SYM(int,GetWindowDisplayIndex,(SDL_Window *a),(a),return) +SDL20_SYM(int,SetWindowDisplayMode,(SDL_Window *a, const SDL_DisplayMode *b),(a,b),return) SDL20_SYM(SDL_Window *,CreateWindow,(const char *a, int b, int c, int d, int e, Uint32 f),(a,b,c,d,e,f),return) SDL20_SYM(SDL_Window *,CreateWindowFrom,(const void *a),(a),return) diff --git a/test/testsprite.c b/test/testsprite.c index 0e2fd17cd..f3705e256 100644 --- a/test/testsprite.c +++ b/test/testsprite.c @@ -20,6 +20,7 @@ SDL_Rect *velocities; int sprites_visible; int debug_flip; Uint16 sprite_w, sprite_h; +int refresh_rate = SDL_REFRESH_DEFAULT; /* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ static void quit(int rc) @@ -182,6 +183,10 @@ int main(int argc, char *argv[]) height = atoi(argv[argc]); --argc; } else + if ( strcmp(argv[argc-1], "-refresh") == 0 ) { + refresh_rate = atoi(argv[argc]); + --argc; + } else if ( strcmp(argv[argc-1], "-bpp") == 0 ) { video_bpp = atoi(argv[argc]); videoflags &= ~SDL_ANYFORMAT; @@ -209,13 +214,14 @@ int main(int argc, char *argv[]) numsprites = atoi(argv[argc]); } else { fprintf(stderr, - "Usage: %s [-bpp N] [-hw] [-flip] [-fast] [-fullscreen] [numsprites]\n", + "Usage: %s [-bpp N] [-refresh N] [-hw] [-flip] [-fast] [-fullscreen] [numsprites]\n", argv[0]); quit(1); } } /* Set video mode */ + SDL_SetRefreshRate(refresh_rate); screen = SDL_SetVideoMode(width, height, video_bpp, videoflags); if ( ! screen ) { fprintf(stderr, "Couldn't set %dx%d video mode: %s\n", From 6a4738f3108ef49f0137770174ae4d9ba3ea67d4 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 7 Aug 2025 19:53:23 -0400 Subject: [PATCH 542/606] SDL12.exports: Fixed SDL_SetRefreshRate line. --- src/SDL12.exports | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SDL12.exports b/src/SDL12.exports index 29423a462..f4e405fb8 100644 --- a/src/SDL12.exports +++ b/src/SDL12.exports @@ -193,7 +193,7 @@ ++'_SDL_GetVideoInfo'.'SDL.dll'.'SDL_GetVideoInfo'.'SDL_GetVideoInfo' ++'_SDL_ListModes'.'SDL.dll'.'SDL_ListModes'.'SDL_ListModes' ++'_SDL_VideoModeOK'.'SDL.dll'.'SDL_VideoModeOK'.'SDL_VideoModeOK' -++'_SDL_SetRefreshRate'.'SDL.dll'.'SDL_SetVideoMode'.'SDL_SetRefreshRate' +++'_SDL_SetRefreshRate'.'SDL.dll'.'SDL_SetRefreshRate'.'SDL_SetRefreshRate' ++'_SDL_SetVideoMode'.'SDL.dll'.'SDL_SetVideoMode'.'SDL_SetVideoMode' ++'_SDL_DisplayFormat'.'SDL.dll'.'SDL_DisplayFormat'.'SDL_DisplayFormat' ++'_SDL_DisplayFormatAlpha'.'SDL.dll'.'SDL_DisplayFormatAlpha'.'SDL_DisplayFormatAlpha' From cc0201143a33a399a8d4f01571cfe5fceec09df5 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Thu, 14 Aug 2025 06:28:20 +0300 Subject: [PATCH 543/606] minor clean-up and sync with latest SDL2 --- src/SDL12_compat.c | 31 +++++++++++++++---------------- src/SDL20_include_wrapper.h | 32 ++++++++++++++++++-------------- 2 files changed, 33 insertions(+), 30 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index b3c2ec565..9b968d130 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -2413,7 +2413,7 @@ AddVidModeToList(VideoModeList *vmode, SDL12_Rect *mode, const Uint16 maxw, cons void *ptr = NULL; int i; - if ( (maxw && (mode->w > maxw)) || (maxh && (mode->h > maxh)) ) { + if ((maxw && (mode->w > maxw)) || (maxh && (mode->h > maxh))) { return 0; /* clamp this one out as too big. */ } @@ -5970,7 +5970,7 @@ LoadOpenGLFunctions(void) } static void -ResolveFauxBackbufferMSAA() +ResolveFauxBackbufferMSAA(void) { const GLboolean has_scissor = OpenGLFuncs.glIsEnabled(GL_SCISSOR_TEST); @@ -6234,15 +6234,7 @@ UnlockVideoRenderer(void) SDL20_UnlockMutex(VideoRendererLock); } -static void HandleInputGrab(SDL12_GrabMode mode); - - -/* SDL_SetRefreshRate was never in an real SDL-1.2 release, but apparently StepMania was maintaining a fork with this API for literally years. */ -DECLSPEC12 void SDLCALL -SDL_SetRefreshRate(int rate) -{ - DesiredRefreshRate = (rate >= 0) ? rate : 0; /* takes effect on next SDL_SetVideoMode call. */ -} +static void HandleInputGrab(SDL12_GrabMode); static SDL12_Surface * SetVideoModeImpl(int width, int height, int bpp, Uint32 flags12) @@ -6287,7 +6279,7 @@ SetVideoModeImpl(int width, int height, int bpp, Uint32 flags12) use_highdpi = (flags12 & SDL12_FULLSCREEN) ? use_gl_scaling : SDL_FALSE; gl_max_fps = SDL12Compat_GetHintInt("SDL12COMPAT_MAX_FPS", 0); - if(gl_max_fps != 0) { + if (gl_max_fps != 0) { OpenGLBuffersSwapTickInterval = 1000.f / gl_max_fps; OpenGLBuffersLastSwapTicks = SDL20_GetTicks(); } @@ -6719,6 +6711,13 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags12) return retval; } +/* SDL_SetRefreshRate was never in an real SDL-1.2 release, but apparently StepMania was maintaining a fork with this API for literally years. */ +DECLSPEC12 void SDLCALL +SDL_SetRefreshRate(int rate) +{ + DesiredRefreshRate = (rate >= 0) ? rate : 0; /* takes effect on next SDL_SetVideoMode call. */ +} + DECLSPEC12 SDL12_Surface * SDLCALL SDL_GetVideoSurface(void) { @@ -7132,7 +7131,7 @@ UpdateRect12to20(SDL12_Surface *surface12, const SDL12_Rect *rect12, SDL_Rect *r /* For manual throttling of screen updates. */ static int -GetDesiredMillisecondsPerFrame() +GetDesiredMillisecondsPerFrame(void) { SDL_DisplayMode mode; if (VideoSurface12->flags & SDL12_FULLSCREEN) { @@ -8213,9 +8212,9 @@ DECLSPEC12 void SDLCALL SDL_GL_SwapBuffers(void) { if (VideoWindow20) { - if(OpenGLBuffersSwapTickInterval != 0.f) { + if (OpenGLBuffersSwapTickInterval != 0.f) { const Uint32 tickDelta = SDL20_GetTicks() - OpenGLBuffersLastSwapTicks; - if(tickDelta < OpenGLBuffersSwapTickInterval) { + if (tickDelta < OpenGLBuffersSwapTickInterval) { SDL20_Delay((int)(OpenGLBuffersSwapTickInterval + 0.5f) - tickDelta); } } @@ -8269,7 +8268,7 @@ SDL_GL_SwapBuffers(void) SDL20_GL_SwapWindow(VideoWindow20); } - if(OpenGLBuffersSwapTickInterval != 0.f) { + if (OpenGLBuffersSwapTickInterval != 0.f) { OpenGLBuffersLastSwapTicks = SDL20_GetTicks(); } } diff --git a/src/SDL20_include_wrapper.h b/src/SDL20_include_wrapper.h index 28eca11f1..50aa440a8 100644 --- a/src/SDL20_include_wrapper.h +++ b/src/SDL20_include_wrapper.h @@ -898,6 +898,7 @@ #define SDL_HasWindowSurface IGNORE_THIS_VERSION_OF_SDL_HasWindowSurface #define SDL_DestroyWindowSurface IGNORE_THIS_VERSION_OF_SDL_DestroyWindowSurface #define SDL_GDKGetDefaultUser IGNORE_THIS_VERSION_OF_SDL_GDKGetDefaultUser +#define SDL_GameControllerGetSteamHandle IGNORE_THIS_VERSION_OF_SDL_GameControllerGetSteamHandle #if defined(_WIN32) || defined(__OS2__) @@ -948,18 +949,6 @@ typedef void (__cdecl *pfnSDL_CurrentEndThread) (unsigned); #endif /* _WIN32 */ -#ifdef SDL_BlitSurface -#undef SDL_BlitSurface -#endif - -#ifdef SDL_mutexP -#undef SDL_mutexP -#endif - -#ifdef SDL_mutexV -#undef SDL_mutexV -#endif - #ifdef SDL_SetError #undef SDL_SetError #endif @@ -4440,8 +4429,23 @@ typedef void (__cdecl *pfnSDL_CurrentEndThread) (unsigned); #undef SDL_GDKGetDefaultUser #endif -/* undefine these macros too: */ -/* redefine using SDL2_xxx, if needed. */ +#ifdef SDL_GameControllerGetSteamHandle +#undef SDL_GameControllerGetSteamHandle +#endif + +/* undefine these macros, too: redefine as SDL2_xxx, if needed. + */ +#ifdef SDL_BlitSurface +#undef SDL_BlitSurface +#endif + +#ifdef SDL_mutexP +#undef SDL_mutexP +#endif + +#ifdef SDL_mutexV +#undef SDL_mutexV +#endif #ifdef SDL_enabled_assert #undef SDL_enabled_assert From 7b66971f8366a9d21869a00c17ac317ebe675a9e Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Wed, 3 Sep 2025 06:45:40 +0300 Subject: [PATCH 544/606] silence some unused-parameter and sign-compare warnings --- src/SDL12_compat.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 9b968d130..88200b222 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1598,6 +1598,8 @@ SDL12Compat_ApplyQuirks(SDL_bool force_x11) SDL12COMPAT_SetEnvAtStartup("SDL_VIDEODRIVER", "x11"); } } + #else + (void)force_x11; #endif if (*exe_name == '\0') { @@ -5419,6 +5421,8 @@ CreateRGBSurface(Uint32 flags12, int width, int height, int depth, Uint32 Rmask, { SDL_Surface *surface20; + (void)flags12; + /* SDL 1.2 checks this. */ if ((width >= 16384) || (height >= 65536)) { SDL20_SetError("Width or height is too large"); @@ -7372,8 +7376,8 @@ SDL_UpdateRect(SDL12_Surface *screen12, Sint32 x, Sint32 y, Uint32 w, Uint32 h) SDL12_Rect rect12; rect12.x = (Sint16) x; rect12.y = (Sint16) y; - rect12.w = (Uint16) (w ? w : screen12->w); - rect12.h = (Uint16) (h ? h : screen12->h); + rect12.w = (Uint16) (w ? w : (unsigned)screen12->w); + rect12.h = (Uint16) (h ? h : (unsigned)screen12->h); SDL_UpdateRects(screen12, 1, &rect12); } } @@ -8054,6 +8058,7 @@ SDL_UnlockYUVOverlay(SDL12_Overlay *overlay12) /*if (overlay12) { overlay12->pixels = NULL; }*/ + (void)overlay12; } DECLSPEC12 void SDLCALL From 5856c414c1879f7146d3f160443fd6549032ad56 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Tue, 16 Sep 2025 21:24:10 +0300 Subject: [PATCH 545/606] update dr_mp3.h from mainstream. --- src/dr_mp3.h | 103 +++++++++++++++++++++++++++++---------------------- 1 file changed, 59 insertions(+), 44 deletions(-) diff --git a/src/dr_mp3.h b/src/dr_mp3.h index beeac70b9..4f776efab 100644 --- a/src/dr_mp3.h +++ b/src/dr_mp3.h @@ -1,6 +1,6 @@ /* MP3 audio decoder. Choice of public domain or MIT-0. See license statements at the end of this file. -dr_mp3 - v0.7.1 - TBD +dr_mp3 - v0.7.2 - TBD David Reid - mackron@gmail.com @@ -78,7 +78,7 @@ extern "C" { #define DRMP3_VERSION_MAJOR 0 #define DRMP3_VERSION_MINOR 7 -#define DRMP3_VERSION_REVISION 1 +#define DRMP3_VERSION_REVISION 2 #define DRMP3_VERSION_STRING DRMP3_XSTRINGIFY(DRMP3_VERSION_MAJOR) "." DRMP3_XSTRINGIFY(DRMP3_VERSION_MINOR) "." DRMP3_XSTRINGIFY(DRMP3_VERSION_REVISION) #include /* For size_t. */ @@ -263,16 +263,45 @@ typedef struct Low Level Push API ================== */ +#define DRMP3_MAX_BITRESERVOIR_BYTES 511 +#define DRMP3_MAX_FREE_FORMAT_FRAME_SIZE 2304 /* more than ISO spec's */ +#define DRMP3_MAX_L3_FRAME_PAYLOAD_BYTES DRMP3_MAX_FREE_FORMAT_FRAME_SIZE /* MUST be >= 320000/8/32000*1152 = 1440 */ + typedef struct { int frame_bytes, channels, sample_rate, layer, bitrate_kbps; } drmp3dec_frame_info; +typedef struct +{ + const drmp3_uint8 *buf; + int pos, limit; +} drmp3_bs; + +typedef struct +{ + const drmp3_uint8 *sfbtab; + drmp3_uint16 part_23_length, big_values, scalefac_compress; + drmp3_uint8 global_gain, block_type, mixed_block_flag, n_long_sfb, n_short_sfb; + drmp3_uint8 table_select[3], region_count[3], subblock_gain[3]; + drmp3_uint8 preflag, scalefac_scale, count1_table, scfsi; +} drmp3_L3_gr_info; + +typedef struct +{ + drmp3_bs bs; + drmp3_uint8 maindata[DRMP3_MAX_BITRESERVOIR_BYTES + DRMP3_MAX_L3_FRAME_PAYLOAD_BYTES]; + drmp3_L3_gr_info gr_info[4]; + float grbuf[2][576], scf[40], syn[18 + 15][2*32]; + drmp3_uint8 ist_pos[2][39]; +} drmp3dec_scratch; + typedef struct { float mdct_overlap[2][9*32], qmf_state[15*2*32]; int reserv, free_format_bytes; drmp3_uint8 header[4], reserv_buf[511]; + drmp3dec_scratch scratch; } drmp3dec; /* Initializes a low level decoder. */ @@ -609,14 +638,10 @@ DRMP3_API const char* drmp3_version_string(void) #define DRMP3_OFFSET_PTR(p, offset) ((void*)((drmp3_uint8*)(p) + (offset))) -#define DRMP3_MAX_FREE_FORMAT_FRAME_SIZE 2304 /* more than ISO spec's */ #ifndef DRMP3_MAX_FRAME_SYNC_MATCHES #define DRMP3_MAX_FRAME_SYNC_MATCHES 10 #endif -#define DRMP3_MAX_L3_FRAME_PAYLOAD_BYTES DRMP3_MAX_FREE_FORMAT_FRAME_SIZE /* MUST be >= 320000/8/32000*1152 = 1440 */ - -#define DRMP3_MAX_BITRESERVOIR_BYTES 511 #define DRMP3_SHORT_BLOCK_TYPE 2 #define DRMP3_STOP_BLOCK_TYPE 3 #define DRMP3_MODE_MONO 3 @@ -672,7 +697,7 @@ DRMP3_API const char* drmp3_version_string(void) #define DRMP3_VMUL_S(x, s) _mm_mul_ps(x, _mm_set1_ps(s)) #define DRMP3_VREV(x) _mm_shuffle_ps(x, x, _MM_SHUFFLE(0, 1, 2, 3)) typedef __m128 drmp3_f4; -#if defined(_MSC_VER) || defined(DR_MP3_ONLY_SIMD) +#if (defined(_MSC_VER) || defined(DR_MP3_ONLY_SIMD)) && !defined(__clang__) #define drmp3_cpuid __cpuid #else static __inline__ __attribute__((always_inline)) void drmp3_cpuid(int CPUInfo[], const int InfoType) @@ -796,11 +821,7 @@ static __inline__ __attribute__((always_inline)) drmp3_int32 drmp3_clip_int16_ar #define DRMP3_FREE(p) free((p)) #endif -typedef struct -{ - const drmp3_uint8 *buf; - int pos, limit; -} drmp3_bs; + typedef struct { @@ -813,24 +834,6 @@ typedef struct drmp3_uint8 tab_offset, code_tab_width, band_count; } drmp3_L12_subband_alloc; -typedef struct -{ - const drmp3_uint8 *sfbtab; - drmp3_uint16 part_23_length, big_values, scalefac_compress; - drmp3_uint8 global_gain, block_type, mixed_block_flag, n_long_sfb, n_short_sfb; - drmp3_uint8 table_select[3], region_count[3], subblock_gain[3]; - drmp3_uint8 preflag, scalefac_scale, count1_table, scfsi; -} drmp3_L3_gr_info; - -typedef struct -{ - drmp3_bs bs; - drmp3_uint8 maindata[DRMP3_MAX_BITRESERVOIR_BYTES + DRMP3_MAX_L3_FRAME_PAYLOAD_BYTES]; - drmp3_L3_gr_info gr_info[4]; - float grbuf[2][576], scf[40], syn[18 + 15][2*32]; - drmp3_uint8 ist_pos[2][39]; -} drmp3dec_scratch; - static void drmp3_bs_init(drmp3_bs *bs, const drmp3_uint8 *data, int bytes) { bs->buf = data; @@ -2327,7 +2330,6 @@ DRMP3_API int drmp3dec_decode_frame(drmp3dec *dec, const drmp3_uint8 *mp3, int m int i = 0, igr, frame_size = 0, success = 1; const drmp3_uint8 *hdr; drmp3_bs bs_frame[1]; - static drmp3dec_scratch scratch; if (mp3_bytes > 4 && dec->header[0] == 0xff && drmp3_hdr_compare(dec->header, mp3)) { @@ -2364,23 +2366,23 @@ DRMP3_API int drmp3dec_decode_frame(drmp3dec *dec, const drmp3_uint8 *mp3, int m if (info->layer == 3) { - int main_data_begin = drmp3_L3_read_side_info(bs_frame, scratch.gr_info, hdr); + int main_data_begin = drmp3_L3_read_side_info(bs_frame, dec->scratch.gr_info, hdr); if (main_data_begin < 0 || bs_frame->pos > bs_frame->limit) { drmp3dec_init(dec); return 0; } - success = drmp3_L3_restore_reservoir(dec, bs_frame, &scratch, main_data_begin); + success = drmp3_L3_restore_reservoir(dec, bs_frame, &dec->scratch, main_data_begin); if (success && pcm != NULL) { for (igr = 0; igr < (DRMP3_HDR_TEST_MPEG1(hdr) ? 2 : 1); igr++, pcm = DRMP3_OFFSET_PTR(pcm, sizeof(drmp3d_sample_t)*576*info->channels)) { - DRMP3_ZERO_MEMORY(scratch.grbuf[0], 576*2*sizeof(float)); - drmp3_L3_decode(dec, &scratch, scratch.gr_info + igr*info->channels, info->channels); - drmp3d_synth_granule(dec->qmf_state, scratch.grbuf[0], 18, info->channels, (drmp3d_sample_t*)pcm, scratch.syn[0]); + DRMP3_ZERO_MEMORY(dec->scratch.grbuf[0], 576*2*sizeof(float)); + drmp3_L3_decode(dec, &dec->scratch, dec->scratch.gr_info + igr*info->channels, info->channels); + drmp3d_synth_granule(dec->qmf_state, dec->scratch.grbuf[0], 18, info->channels, (drmp3d_sample_t*)pcm, dec->scratch.syn[0]); } } - drmp3_L3_save_reservoir(dec, &scratch); + drmp3_L3_save_reservoir(dec, &dec->scratch); } else { #ifdef DR_MP3_ONLY_MP3 @@ -2394,15 +2396,15 @@ DRMP3_API int drmp3dec_decode_frame(drmp3dec *dec, const drmp3_uint8 *mp3, int m drmp3_L12_read_scale_info(hdr, bs_frame, sci); - DRMP3_ZERO_MEMORY(scratch.grbuf[0], 576*2*sizeof(float)); + DRMP3_ZERO_MEMORY(dec->scratch.grbuf[0], 576*2*sizeof(float)); for (i = 0, igr = 0; igr < 3; igr++) { - if (12 == (i += drmp3_L12_dequantize_granule(scratch.grbuf[0] + i, bs_frame, sci, info->layer | 1))) + if (12 == (i += drmp3_L12_dequantize_granule(dec->scratch.grbuf[0] + i, bs_frame, sci, info->layer | 1))) { i = 0; - drmp3_L12_apply_scf_384(sci, sci->scf + igr, scratch.grbuf[0]); - drmp3d_synth_granule(dec->qmf_state, scratch.grbuf[0], 12, info->channels, (drmp3d_sample_t*)pcm, scratch.syn[0]); - DRMP3_ZERO_MEMORY(scratch.grbuf[0], 576*2*sizeof(float)); + drmp3_L12_apply_scf_384(sci, sci->scf + igr, dec->scratch.grbuf[0]); + drmp3d_synth_granule(dec->qmf_state, dec->scratch.grbuf[0], 12, info->channels, (drmp3d_sample_t*)pcm, dec->scratch.syn[0]); + DRMP3_ZERO_MEMORY(dec->scratch.grbuf[0], 576*2*sizeof(float)); pcm = DRMP3_OFFSET_PTR(pcm, sizeof(drmp3d_sample_t)*384*info->channels); } if (bs_frame->pos > bs_frame->limit) @@ -3275,6 +3277,13 @@ static drmp3_bool32 drmp3_init_internal(drmp3* pMP3, drmp3_read_proc onRead, drm /* The start offset needs to be moved to the end of this frame so it's not included in any audio processing after seeking. */ pMP3->streamStartOffset += (drmp3_uint32)(firstFrameInfo.frame_bytes); pMP3->streamCursor = pMP3->streamStartOffset; + + /* + The internal decoder needs to be reset to clear out any state. If we don't reset this state, it's possible for + there to be inconsistencies in the number of samples read when reading to the end of the stream depending on + whether or not the caller seeks to the start of the stream. + */ + drmp3dec_init(&pMP3->decoder); } } else { /* Failed to read the side info. */ @@ -4010,7 +4019,7 @@ static drmp3_bool32 drmp3__on_tell_stdio(void* pUserData, drmp3_int64* pCursor) DRMP3_ASSERT(pFileStdio != NULL); DRMP3_ASSERT(pCursor != NULL); -#if defined(_WIN32) +#if defined(_WIN32) && !defined(NXDK) #if defined(_MSC_VER) && _MSC_VER > 1200 result = _ftelli64(pFileStdio); #else @@ -5019,8 +5028,14 @@ DIFFERENCES BETWEEN minimp3 AND dr_mp3 /* REVISION HISTORY ================ -v0.7.1 - TBD +v0.7.2 - TBD + - Reduce stack space to improve robustness on embedded systems. + - Fix a compilation error with MSVC Clang toolset relating to cpuid. + +v0.7.1 - 2025-09-10 - Silence a warning with GCC. + - Fix an error with the NXDK build. + - Fix a decoding inconsistency when seeking. Prior to this change, reading to the end of the stream immediately after initializing will result in a different number of samples read than if the stream is seeked to the start and read to the end. v0.7.0 - 2025-07-23 - The old `DRMP3_IMPLEMENTATION` has been removed. Use `DR_MP3_IMPLEMENTATION` instead. The reason for this change is that in the future everything will eventually be using the underscored naming convention in the future, so `drmp3` will become `dr_mp3`. From afabbb5148ab1920958d93a3c7fb3c1fb004b7a6 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Tue, 30 Sep 2025 13:06:59 +0100 Subject: [PATCH 546/606] Treat DEBUG_INVOCATION=1 as equivalent to SDL12COMPAT_DEBUG_LOGGING=1 In the same spirit as https://github.com/libsdl-org/SDL/issues/12275, if we enable a reasonable level of debug output whenever this variable is set, it becomes a convenient way for users to request a more verbose (but not overwhelming) amount of output. SDL 3 and GLib already do this. Explicitly setting SDL12COMPAT_DEBUG_LOGGING=0 can override this, if it becomes necessary for whatever reason. Signed-off-by: Simon McVittie --- src/SDL12_compat.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 88200b222..a0e274438 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1222,6 +1222,8 @@ static const char *SDL12COMPAT_GetEnvAtStartup(const char *name) static SDL_bool SDL12COMPAT_CheckDebugLogging(void) { const char *value = SDL12COMPAT_GetEnvAtStartup("SDL12COMPAT_DEBUG_LOGGING"); + if (value == NULL) + value = SDL12COMPAT_GetEnvAtStartup("DEBUG_INVOCATION"); return ((value != NULL) && SDL12COMPAT_strequal(value, "1")) ? SDL_TRUE : SDL_FALSE; } From 6152f8de38fa9188e280dbbba5d37b15a3a499b5 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 30 Sep 2025 09:20:06 -0700 Subject: [PATCH 547/606] Fixed style --- src/SDL12_compat.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index a0e274438..29dd198c6 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1222,9 +1222,10 @@ static const char *SDL12COMPAT_GetEnvAtStartup(const char *name) static SDL_bool SDL12COMPAT_CheckDebugLogging(void) { const char *value = SDL12COMPAT_GetEnvAtStartup("SDL12COMPAT_DEBUG_LOGGING"); - if (value == NULL) + if (!value) { value = SDL12COMPAT_GetEnvAtStartup("DEBUG_INVOCATION"); - return ((value != NULL) && SDL12COMPAT_strequal(value, "1")) ? SDL_TRUE : SDL_FALSE; + } + return (value && SDL12COMPAT_strequal(value, "1")) ? SDL_TRUE : SDL_FALSE; } /* Obviously we can't use SDL_LoadObject() to load SDL2. :) */ From 2c3d8fbd0defd50a37973a8e91ea5d3f5afb89f8 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Thu, 2 Oct 2025 20:18:57 +0200 Subject: [PATCH 548/606] ci: remove macos-13 job (#369) macos-13 machine will be retired soon --- .github/workflows/main.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 3a2245654..4b82bd595 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -14,7 +14,6 @@ jobs: - { name: Linux-x86_64, os: ubuntu-24.04, flags: -GNinja } - { name: Linux-arm64, os: ubuntu-24.04-arm, flags: -GNinja } - { name: MacOS-arm64, os: macos-latest } - - { name: MacOS-x86_64, os: macos-13 } steps: - name: Setup Linux dependencies if: startsWith(runner.os, 'Linux') From fbb588618c22cf0d6d99328e39e64ef0d744a3c5 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Thu, 23 Oct 2025 03:11:56 +0300 Subject: [PATCH 549/606] update dr_mp3.h from mainstream. --- src/dr_mp3.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dr_mp3.h b/src/dr_mp3.h index 4f776efab..93e02b5c9 100644 --- a/src/dr_mp3.h +++ b/src/dr_mp3.h @@ -1251,7 +1251,7 @@ static float drmp3_L3_ldexp_q2(float y, int exp_q2) I've had reports of GCC 14 throwing an incorrect -Wstringop-overflow warning here. This is an attempt to silence this warning. */ -#if (defined(__GNUC__) && (__GNUC__ >= 14)) && !defined(__clang__) +#if (defined(__GNUC__) && (__GNUC__ >= 13)) && !defined(__clang__) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wstringop-overflow" #endif @@ -1316,7 +1316,7 @@ static void drmp3_L3_decode_scalefactors(const drmp3_uint8 *hdr, drmp3_uint8 *is scf[i] = drmp3_L3_ldexp_q2(gain, iscf[i] << scf_shift); } } -#if (defined(__GNUC__) && (__GNUC__ >= 14)) && !defined(__clang__) +#if (defined(__GNUC__) && (__GNUC__ >= 13)) && !defined(__clang__) #pragma GCC diagnostic pop #endif From 11e36ff48e5f9f7dd92c52e6a7869dc2ccf15487 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sat, 25 Oct 2025 11:33:23 -0700 Subject: [PATCH 550/606] Add cmake uninstall target (thanks @ChillerDragon!) --- CMakeLists.txt | 7 +++++++ cmake/cmake_uninstall.cmake.in | 17 +++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 cmake/cmake_uninstall.cmake.in diff --git a/CMakeLists.txt b/CMakeLists.txt index 0516508c1..45f346d2b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -295,6 +295,13 @@ if(SDL12DEVEL) configure_file("${CMAKE_CURRENT_SOURCE_DIR}/sdl-config.in" "${CMAKE_CURRENT_BINARY_DIR}/sdl-config" @ONLY) install(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/sdl-config" DESTINATION bin) + + # uninstall + if(NOT TARGET uninstall) + configure_file(cmake/cmake_uninstall.cmake.in "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" IMMEDIATE @ONLY) + add_custom_target(uninstall + COMMAND ${CMAKE_COMMAND} -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake") + endif() endif() set(SOEXT ${CMAKE_SHARED_LIBRARY_SUFFIX}) diff --git a/cmake/cmake_uninstall.cmake.in b/cmake/cmake_uninstall.cmake.in new file mode 100644 index 000000000..9a59b4f48 --- /dev/null +++ b/cmake/cmake_uninstall.cmake.in @@ -0,0 +1,17 @@ +if (NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt") + message(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_BINARY_DIR@/install_manifest.txt\"") +endif() + +file(READ "@CMAKE_BINARY_DIR@/install_manifest.txt" files) +string(REGEX REPLACE "\n" ";" files "${files}") +foreach(file ${files}) + message(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"") + execute_process( + COMMAND @CMAKE_COMMAND@ -E remove "$ENV{DESTDIR}${file}" + OUTPUT_VARIABLE rm_out + RESULT_VARIABLE rm_retval + ) + if(NOT ${rm_retval} EQUAL 0) + message(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"") + endif (NOT ${rm_retval} EQUAL 0) +endforeach() From 1bda9e4ee12b79e90370b16b25d46ff481d53614 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sat, 25 Oct 2025 12:26:18 -0700 Subject: [PATCH 551/606] Capslock only gets a key up event when toggled off Fixes https://github.com/libsdl-org/sdl12-compat/issues/331 --- src/SDL12_compat.c | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 29dd198c6..e31a90573 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -4909,6 +4909,11 @@ EventFilter20to12(void *data, SDL_Event *event20) event12.key.keysym.sym = Scancode20toKeysym12(event20->key.keysym.scancode); } + if (event12.key.keysym.sym == SDLK12_CAPSLOCK) { + /* SDL 1.2 only sends capslock key events on keydown */ + return 1; + } + if (KeyRepeatNextTicks) { SDL_assert(KeyRepeatEvent.type == SDL12_KEYDOWN); if (KeyRepeatEvent.key.keysym.sym == event12.key.keysym.sym) { @@ -4937,18 +4942,35 @@ EventFilter20to12(void *data, SDL_Event *event20) } if (TranslateKeyboardLayout) { - PendingKeydownEvent.key.keysym.sym = Keysym20to12(event20->key.keysym.sym); + event12.key.keysym.sym = Keysym20to12(event20->key.keysym.sym); } else { - PendingKeydownEvent.key.keysym.sym = Scancode20toKeysym12(event20->key.keysym.scancode); + event12.key.keysym.sym = Scancode20toKeysym12(event20->key.keysym.scancode); } - KeyState[PendingKeydownEvent.key.keysym.sym] = event20->key.state; + if (event12.key.keysym.sym == SDLK12_CAPSLOCK) { + /* SDL 1.2 toggles capslock on keypress */ + if (KeyState[SDLK12_CAPSLOCK]) { + KeyState[SDLK12_CAPSLOCK] = SDL_RELEASED; + + event12.type = SDL12_KEYUP; + event12.key.which = 0; + event12.key.state = SDL_RELEASED; + event12.key.keysym.scancode = Scancode20to12(event20->key.keysym.scancode); + event12.key.keysym.sym = SDLK12_CAPSLOCK; + event12.key.keysym.mod = event20->key.keysym.mod & ~KMOD_CAPS; + event12.key.keysym.unicode = 0; + break; + } + } + + KeyState[event12.key.keysym.sym] = event20->key.state; - PendingKeydownEvent.type = (event20->type == SDL_KEYDOWN) ? SDL12_KEYDOWN : SDL12_KEYUP; + PendingKeydownEvent.type = SDL12_KEYDOWN; PendingKeydownEvent.key.which = 0; PendingKeydownEvent.key.state = event20->key.state; /* turns out that some apps actually made use of the hardware scancodes (checking for platform beforehand) */ PendingKeydownEvent.key.keysym.scancode = Scancode20to12(event20->key.keysym.scancode); + PendingKeydownEvent.key.keysym.sym = event12.key.keysym.sym; PendingKeydownEvent.key.keysym.mod = event20->key.keysym.mod; /* these match up between 1.2 and 2.0! */ PendingKeydownEvent.key.keysym.unicode = 0; From 192cef725169c0732175884ad1bebe430bb0034b Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sat, 25 Oct 2025 12:42:31 -0700 Subject: [PATCH 552/606] Don't repeat control keys Also, numlock has the same toggling behavior as capslock in SDL 1.2 Fixes https://github.com/libsdl-org/sdl12-compat/issues/332 --- src/SDL12_compat.c | 45 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 9 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index e31a90573..1b82aa1ca 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -4759,6 +4759,27 @@ static int DecodeUTF8Char(char **ptr) return value; } +static int IsRepeatable(SDL12Key key) +{ + switch (key) { + case SDLK12_UNKNOWN: + case SDLK12_NUMLOCK: + case SDLK12_CAPSLOCK: + case SDLK12_LCTRL: + case SDLK12_RCTRL: + case SDLK12_LSHIFT: + case SDLK12_RSHIFT: + case SDLK12_LALT: + case SDLK12_RALT: + case SDLK12_LMETA: + case SDLK12_RMETA: + case SDLK12_MODE: + return 0; + default: + return 1; + } +} + /* Add the pending KEYDOWN event to the EventQueue, possibly with 'unicode' set * Returns 1 if there was a pending event. */ static int FlushPendingKeydownEvent(Uint32 unicode) @@ -4770,7 +4791,7 @@ static int FlushPendingKeydownEvent(Uint32 unicode) PendingKeydownEvent.key.keysym.unicode = unicode; PushEventIfNotFiltered(&PendingKeydownEvent); - if (KeyRepeatDelay) { + if (KeyRepeatDelay && IsRepeatable(PendingKeydownEvent.key.keysym.sym)) { SDL20_memcpy(&KeyRepeatEvent, &PendingKeydownEvent, sizeof (SDL12_Event)); /* SDL 1.2 waits for the delay, and then a full interval past that before the first repeat is reported. */ KeyRepeatNextTicks = SDL20_GetTicks() + KeyRepeatDelay + KeyRepeatInterval; @@ -4909,8 +4930,9 @@ EventFilter20to12(void *data, SDL_Event *event20) event12.key.keysym.sym = Scancode20toKeysym12(event20->key.keysym.scancode); } - if (event12.key.keysym.sym == SDLK12_CAPSLOCK) { - /* SDL 1.2 only sends capslock key events on keydown */ + if (event12.key.keysym.sym == SDLK12_CAPSLOCK || + event12.key.keysym.sym == SDLK12_NUMLOCK) { + /* SDL 1.2 only sends capslock and numlock key events on keydown */ return 1; } @@ -4947,18 +4969,23 @@ EventFilter20to12(void *data, SDL_Event *event20) event12.key.keysym.sym = Scancode20toKeysym12(event20->key.keysym.scancode); } - if (event12.key.keysym.sym == SDLK12_CAPSLOCK) { - /* SDL 1.2 toggles capslock on keypress */ - if (KeyState[SDLK12_CAPSLOCK]) { - KeyState[SDLK12_CAPSLOCK] = SDL_RELEASED; + if (event12.key.keysym.sym == SDLK12_CAPSLOCK || + event12.key.keysym.sym == SDLK12_NUMLOCK) { + /* SDL 1.2 toggles capslock and numlock on keypress */ + if (KeyState[event12.key.keysym.sym]) { + KeyState[event12.key.keysym.sym] = SDL_RELEASED; event12.type = SDL12_KEYUP; event12.key.which = 0; event12.key.state = SDL_RELEASED; event12.key.keysym.scancode = Scancode20to12(event20->key.keysym.scancode); - event12.key.keysym.sym = SDLK12_CAPSLOCK; - event12.key.keysym.mod = event20->key.keysym.mod & ~KMOD_CAPS; + event12.key.keysym.mod = event20->key.keysym.mod; event12.key.keysym.unicode = 0; + if (event12.key.keysym.sym == SDLK12_CAPSLOCK) { + event12.key.keysym.mod &= ~KMOD12_CAPS; + } else if (event12.key.keysym.sym == SDLK12_NUMLOCK) { + event12.key.keysym.mod &= ~KMOD12_NUM; + } break; } } From dfa6cc2f0376c4cd7acc7759716c431bb22d884b Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sat, 25 Oct 2025 17:07:08 -0700 Subject: [PATCH 553/606] Scale coordinates used in SDL_WarpMouse() Fixes https://github.com/libsdl-org/sdl12-compat/issues/367 --- src/SDL12_compat.c | 25 +++++++++++++++++++++++++ src/SDL20_syms.h | 3 +++ 2 files changed, 28 insertions(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 1b82aa1ca..cedc803e0 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -7706,6 +7706,31 @@ SDL_WarpMouse(Uint16 x, Uint16 y) MousePosition.y = (int) y; } else { if (VideoWindow20) { + SDL_Rect viewport; + float scale_x, scale_y; + + if (OpenGLLogicalScalingFBO) { + int physical_w, physical_h; + + /* we want to scale into the window size, which is dpi-scaled */ + SDL20_GetWindowSize(VideoWindow20, &physical_w, &physical_h); + + viewport = GetOpenGLLogicalScalingViewport(physical_w, physical_h); + + scale_x = (float)viewport.w / OpenGLLogicalScalingWidth; + scale_y = (float)viewport.h / OpenGLLogicalScalingHeight; + } else { + SDL20_RenderGetViewport(VideoRenderer20, &viewport); + SDL20_RenderGetScale(VideoRenderer20, &scale_x, &scale_y); + viewport.x = (int)SDL20_lroundf(viewport.x * scale_x); + viewport.y = (int)SDL20_lroundf(viewport.y * scale_y); + viewport.w = (int)SDL20_lroundf(viewport.w * scale_x); + viewport.h = (int)SDL20_lroundf(viewport.h * scale_y); + } + + x = (int)SDL20_lroundf(viewport.x + (x * scale_x)); + y = (int)SDL20_lroundf(viewport.y + (y * scale_y)); + SDL20_WarpMouseInWindow(VideoWindow20, x, y); } } diff --git a/src/SDL20_syms.h b/src/SDL20_syms.h index 36af4bca7..1fc50b0f9 100644 --- a/src/SDL20_syms.h +++ b/src/SDL20_syms.h @@ -313,6 +313,7 @@ SDL20_SYM_PASSTHROUGH(int,iconv_close,(SDL_iconv_t a),(a),return) SDL20_SYM_PASSTHROUGH(size_t,iconv,(SDL_iconv_t a, const char **b, size_t *c, char **d, size_t *e),(a,b,c,d,e),return) SDL20_SYM_PASSTHROUGH(char *,iconv_string,(const char *a, const char *b, const char *c, size_t d),(a,b,c,d),return) SDL20_SYM(int,setenv,(const char *a, const char *b, int c),(a,b,c),return) +SDL20_SYM(long,lroundf,(float a),(a),return) SDL20_SYM(double,fabs,(double a),(a),return) SDL20_SYM(double,ceil,(double a),(a),return) @@ -320,6 +321,8 @@ SDL20_SYM(double,floor,(double a),(a),return) SDL20_SYM(SDL_Renderer *,CreateRenderer,(SDL_Window *a, int b, Uint32 c),(a,b,c),return) SDL20_SYM(int,GetRendererInfo,(SDL_Renderer *a, SDL_RendererInfo *b),(a,b),return) +SDL20_SYM(void,RenderGetScale,(SDL_Renderer *a, float *b, float *c),(a,b,c),return) +SDL20_SYM(void,RenderGetViewport,(SDL_Renderer *a, SDL_Rect *b),(a,b),return) SDL20_SYM(SDL_Texture *,CreateTexture,(SDL_Renderer *a, Uint32 b, int c, int d, int e),(a,b,c,d,e),return) SDL20_SYM(int,LockTexture,(SDL_Texture *a, const SDL_Rect *b, void **c, int *d),(a,b,c,d),return) SDL20_SYM(void,UnlockTexture,(SDL_Texture *a),(a),) From 8149d5720abf050ea506fe6ed48eee0e6060bafe Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sat, 25 Oct 2025 17:46:16 -0700 Subject: [PATCH 554/606] Input grab should persist past setting the video mode Fixes https://github.com/libsdl-org/sdl12-compat/issues/368 --- src/SDL12_compat.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index cedc803e0..e9c08602c 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -975,6 +975,7 @@ static SDL12_VideoInfo VideoInfo12; static SDL12_Palette VideoInfoPalette12; static SDL12_PixelFormat VideoInfoVfmt12; static SDL_PixelFormat *VideoInfoVfmt20 = NULL; +static SDL_bool VideoWindowGrabWanted = SDL_FALSE; static SDL_bool VideoWindowGrabbed = SDL_FALSE; static SDL_bool VideoCursorHidden = SDL_FALSE; static SDL_bool SetVideoModeInProgress = SDL_FALSE; @@ -2708,6 +2709,7 @@ Init12Video(void) VideoDisplayIndex = GetVideoDisplay(); SwapInterval = 0; + VideoWindowGrabWanted = SDL_FALSE; VideoWindowGrabbed = SDL_FALSE; VideoCursorHidden = SDL_FALSE; SDL20_ShowCursor(1); @@ -6290,7 +6292,7 @@ UnlockVideoRenderer(void) SDL20_UnlockMutex(VideoRendererLock); } -static void HandleInputGrab(SDL12_GrabMode); +static void UpdateInputGrab(void); static SDL12_Surface * SetVideoModeImpl(int width, int height, int bpp, Uint32 flags12) @@ -6741,10 +6743,7 @@ SetVideoModeImpl(int width, int height, int bpp, Uint32 flags12) SDL20_RaiseWindow(VideoWindow20); - /* SDL 1.2 always grabbed input if the video mode was fullscreen. */ - if (VideoSurface12->flags & SDL12_FULLSCREEN) { - HandleInputGrab(SDL12_GRAB_ON); - } + UpdateInputGrab(); if ((flags12 & SDL12_OPENGL) == 0) { /* see notes above these functions about GL context resetting. Force a lock/unlock here to set that up. */ @@ -7675,15 +7674,13 @@ SDL_ShowCursor(int toggle) } static void -HandleInputGrab(SDL12_GrabMode mode) +UpdateInputGrab(void) { /* SDL 1.2 always grabbed input if the video mode was fullscreen. */ const SDL_bool isfullscreen = (VideoSurface12 && VideoSurface12->surface20 && (VideoSurface12->flags & SDL12_FULLSCREEN)) ? SDL_TRUE : SDL_FALSE; - const SDL_bool wantgrab = (isfullscreen || (mode == SDL12_GRAB_ON)) ? SDL_TRUE : SDL_FALSE; - if (VideoWindowGrabbed != wantgrab) { - if (VideoWindow20) { - SDL20_SetWindowGrab(VideoWindow20, wantgrab); - } + const SDL_bool wantgrab = (VideoWindowGrabWanted || isfullscreen); + if (VideoWindow20) { + SDL20_SetWindowGrab(VideoWindow20, wantgrab); VideoWindowGrabbed = wantgrab; UpdateRelativeMouseMode(); } @@ -7693,9 +7690,10 @@ DECLSPEC12 SDL12_GrabMode SDLCALL SDL_WM_GrabInput(SDL12_GrabMode mode) { if (mode != SDL12_GRAB_QUERY) { - HandleInputGrab(mode); + VideoWindowGrabWanted = mode; + UpdateInputGrab(); } - return VideoWindowGrabbed ? SDL12_GRAB_ON : SDL12_GRAB_OFF; + return VideoWindowGrabWanted ? SDL12_GRAB_ON : SDL12_GRAB_OFF; } DECLSPEC12 void SDLCALL From 2d3c96bf024153ed18cb1e41ce8e452fbcc4dc9e Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sat, 25 Oct 2025 18:52:41 -0700 Subject: [PATCH 555/606] Prevent continuous round trips to the X server when warping Fixes https://github.com/libsdl-org/sdl12-compat/issues/340 --- src/SDL12_compat.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index e9c08602c..c7051ca8c 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -7702,6 +7702,17 @@ SDL_WarpMouse(Uint16 x, Uint16 y) if (MouseInputIsRelative) { /* we have to track this ourselves, in case app calls SDL_GetMouseState(). */ MousePosition.x = (int) x; MousePosition.y = (int) y; + } else if (x == MousePosition.x && y == MousePosition.y) { + /* There's no movement needed, just generate an internal event */ + SDL12_Event event; + event.type = SDL12_MOUSEMOTION; + event.motion.which = 0; + event.motion.state = SDL_GetMouseState(NULL, NULL); + event.motion.x = x; + event.motion.y = y; + event.motion.xrel = 0; + event.motion.yrel = 0; + PushEventIfNotFiltered(&event); } else { if (VideoWindow20) { SDL_Rect viewport; From ae1a793d3f77686b888f540ed60ebd9b47e4edeb Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sun, 26 Oct 2025 09:05:57 -0700 Subject: [PATCH 556/606] Improved modifier key handling Fixes https://github.com/libsdl-org/sdl12-compat/issues/338 --- src/SDL12_compat.c | 60 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 54 insertions(+), 6 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index c7051ca8c..331e962b2 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -5003,6 +5003,41 @@ EventFilter20to12(void *data, SDL_Event *event20) PendingKeydownEvent.key.keysym.mod = event20->key.keysym.mod; /* these match up between 1.2 and 2.0! */ PendingKeydownEvent.key.keysym.unicode = 0; + /* SDL 1.2 did not include modifiers in the keys that changed them */ + if (PendingKeydownEvent.key.keysym.mod) { + switch (PendingKeydownEvent.key.keysym.sym) { + case SDLK12_LCTRL: + PendingKeydownEvent.key.keysym.mod &= ~KMOD12_LCTRL; + break; + case SDLK12_RCTRL: + PendingKeydownEvent.key.keysym.mod &= ~KMOD12_RCTRL; + break; + case SDLK12_LSHIFT: + PendingKeydownEvent.key.keysym.mod &= ~KMOD12_LSHIFT; + break; + case SDLK12_RSHIFT: + PendingKeydownEvent.key.keysym.mod &= ~KMOD12_RSHIFT; + break; + case SDLK12_LALT: + PendingKeydownEvent.key.keysym.mod &= ~KMOD12_LALT; + break; + case SDLK12_RALT: + PendingKeydownEvent.key.keysym.mod &= ~KMOD12_RALT; + break; + case SDLK12_LMETA: + PendingKeydownEvent.key.keysym.mod &= ~KMOD12_LMETA; + break; + case SDLK12_RMETA: + PendingKeydownEvent.key.keysym.mod &= ~KMOD12_RMETA; + break; + case SDLK12_MODE: + PendingKeydownEvent.key.keysym.mod &= ~KMOD12_MODE; + break; + default: + break; + } + } + /* If Unicode is not enabled, flush all KEYDOWN events immediately. */ if (!EnabledUnicode) { FlushPendingKeydownEvent(0); @@ -5031,13 +5066,26 @@ EventFilter20to12(void *data, SDL_Event *event20) default: /* not a supported control character when CTRL is pressed, text events aren't sent so use fallback for unicode */ - if (PendingKeydownEvent.key.keysym.mod & KMOD_CTRL) { - const char *keyName = SDL_GetKeyName(PendingKeydownEvent.key.keysym.sym); - /* use key name as unicode if it's a single character */ - if (keyName[0] && !keyName[1]) - FlushPendingKeydownEvent(keyName[0]); - else + if (event20->key.keysym.mod & KMOD_CTRL) { + switch (PendingKeydownEvent.key.keysym.sym) { + case SDLK12_UNKNOWN: FlushPendingKeydownEvent(0); + break; + case SDLK_SPACE: + FlushPendingKeydownEvent(' '); + break; + case SDLK_DELETE: + FlushPendingKeydownEvent('\x7F'); + break; + default: + if (event20->key.keysym.sym & SDLK_SCANCODE_MASK) { + /* This key has no associated unicode text */ + FlushPendingKeydownEvent(0); + } else { + FlushPendingKeydownEvent(event20->key.keysym.sym); + } + break; + } } break; } From 266e1895a9e5357313b03f612fe2109971313575 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sun, 26 Oct 2025 09:35:17 -0700 Subject: [PATCH 557/606] Updated copyright for 2025 --- LICENSE.txt | 2 +- include/SDL/SDL.h | 2 +- include/SDL/SDL_active.h | 2 +- include/SDL/SDL_audio.h | 2 +- include/SDL/SDL_byteorder.h | 2 +- include/SDL/SDL_cdrom.h | 2 +- include/SDL/SDL_config.h | 2 +- include/SDL/SDL_copying.h | 2 +- include/SDL/SDL_cpuinfo.h | 2 +- include/SDL/SDL_endian.h | 2 +- include/SDL/SDL_error.h | 2 +- include/SDL/SDL_events.h | 2 +- include/SDL/SDL_getenv.h | 2 +- include/SDL/SDL_joystick.h | 2 +- include/SDL/SDL_keyboard.h | 2 +- include/SDL/SDL_keysym.h | 2 +- include/SDL/SDL_loadso.h | 2 +- include/SDL/SDL_main.h | 2 +- include/SDL/SDL_mouse.h | 2 +- include/SDL/SDL_mutex.h | 2 +- include/SDL/SDL_name.h | 2 +- include/SDL/SDL_opengl.h | 2 +- include/SDL/SDL_platform.h | 2 +- include/SDL/SDL_quit.h | 2 +- include/SDL/SDL_rwops.h | 2 +- include/SDL/SDL_stdinc.h | 2 +- include/SDL/SDL_syswm.h | 2 +- include/SDL/SDL_thread.h | 2 +- include/SDL/SDL_timer.h | 2 +- include/SDL/SDL_types.h | 2 +- include/SDL/SDL_version.h | 2 +- include/SDL/SDL_video.h | 2 +- include/SDL/begin_code.h | 2 +- include/SDL/close_code.h | 2 +- src/SDL12_compat.c | 2 +- src/SDL12_compat_objc.m | 2 +- src/SDL20_include_wrapper.h | 2 +- src/SDL20_syms.h | 2 +- src/default_cursor.h | 2 +- src/version.rc | 2 +- src/x86_msvc.h | 2 +- 41 files changed, 41 insertions(+), 41 deletions(-) diff --git a/LICENSE.txt b/LICENSE.txt index a705f9b50..b9d0beff3 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,4 +1,4 @@ -Copyright (C) 1997-2024 Sam Lantinga +Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL.h b/include/SDL/SDL.h index 1b3f0257f..b94b832e1 100644 --- a/include/SDL/SDL.h +++ b/include/SDL/SDL.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_active.h b/include/SDL/SDL_active.h index 0e46ef0c0..3d139c349 100644 --- a/include/SDL/SDL_active.h +++ b/include/SDL/SDL_active.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_audio.h b/include/SDL/SDL_audio.h index a5a3afa17..a9972e84b 100644 --- a/include/SDL/SDL_audio.h +++ b/include/SDL/SDL_audio.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_byteorder.h b/include/SDL/SDL_byteorder.h index cbd0492e2..1c78c4464 100644 --- a/include/SDL/SDL_byteorder.h +++ b/include/SDL/SDL_byteorder.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_cdrom.h b/include/SDL/SDL_cdrom.h index 1ebfdfe0c..acd4f7e3f 100644 --- a/include/SDL/SDL_cdrom.h +++ b/include/SDL/SDL_cdrom.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_config.h b/include/SDL/SDL_config.h index 407a20252..ac191c19a 100644 --- a/include/SDL/SDL_config.h +++ b/include/SDL/SDL_config.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_copying.h b/include/SDL/SDL_copying.h index 7b5db740f..d0bc88f07 100644 --- a/include/SDL/SDL_copying.h +++ b/include/SDL/SDL_copying.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_cpuinfo.h b/include/SDL/SDL_cpuinfo.h index 4b86e56f4..adc0b3a6c 100644 --- a/include/SDL/SDL_cpuinfo.h +++ b/include/SDL/SDL_cpuinfo.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_endian.h b/include/SDL/SDL_endian.h index e5ea9cdc6..a44c40b1a 100644 --- a/include/SDL/SDL_endian.h +++ b/include/SDL/SDL_endian.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_error.h b/include/SDL/SDL_error.h index c785de5de..ee13381c3 100644 --- a/include/SDL/SDL_error.h +++ b/include/SDL/SDL_error.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_events.h b/include/SDL/SDL_events.h index 30915fb16..64774baa6 100644 --- a/include/SDL/SDL_events.h +++ b/include/SDL/SDL_events.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_getenv.h b/include/SDL/SDL_getenv.h index d597c9fdd..3db709c2a 100644 --- a/include/SDL/SDL_getenv.h +++ b/include/SDL/SDL_getenv.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_joystick.h b/include/SDL/SDL_joystick.h index 84507bd87..d51793481 100644 --- a/include/SDL/SDL_joystick.h +++ b/include/SDL/SDL_joystick.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_keyboard.h b/include/SDL/SDL_keyboard.h index 3212acbea..7f68d6b4c 100644 --- a/include/SDL/SDL_keyboard.h +++ b/include/SDL/SDL_keyboard.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_keysym.h b/include/SDL/SDL_keysym.h index 7c3310fcf..053ae4351 100644 --- a/include/SDL/SDL_keysym.h +++ b/include/SDL/SDL_keysym.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_loadso.h b/include/SDL/SDL_loadso.h index 5df9471e8..5b01a9463 100644 --- a/include/SDL/SDL_loadso.h +++ b/include/SDL/SDL_loadso.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_main.h b/include/SDL/SDL_main.h index aa1b1acf8..4c347266a 100644 --- a/include/SDL/SDL_main.h +++ b/include/SDL/SDL_main.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_mouse.h b/include/SDL/SDL_mouse.h index 86d0ab255..36d762385 100644 --- a/include/SDL/SDL_mouse.h +++ b/include/SDL/SDL_mouse.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_mutex.h b/include/SDL/SDL_mutex.h index 709b2d8b6..25a1b3f39 100644 --- a/include/SDL/SDL_mutex.h +++ b/include/SDL/SDL_mutex.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_name.h b/include/SDL/SDL_name.h index 9bac06a74..635c288a0 100644 --- a/include/SDL/SDL_name.h +++ b/include/SDL/SDL_name.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_opengl.h b/include/SDL/SDL_opengl.h index b87477eb9..776541a20 100644 --- a/include/SDL/SDL_opengl.h +++ b/include/SDL/SDL_opengl.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_platform.h b/include/SDL/SDL_platform.h index 9e667b8e4..72f7dc9b6 100644 --- a/include/SDL/SDL_platform.h +++ b/include/SDL/SDL_platform.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_quit.h b/include/SDL/SDL_quit.h index 5c24c3eb9..505a01003 100644 --- a/include/SDL/SDL_quit.h +++ b/include/SDL/SDL_quit.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_rwops.h b/include/SDL/SDL_rwops.h index 052c23ae0..5b2bb5539 100644 --- a/include/SDL/SDL_rwops.h +++ b/include/SDL/SDL_rwops.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_stdinc.h b/include/SDL/SDL_stdinc.h index dd4c25c81..da7e7624e 100644 --- a/include/SDL/SDL_stdinc.h +++ b/include/SDL/SDL_stdinc.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_syswm.h b/include/SDL/SDL_syswm.h index 8e6f70639..c32f7f398 100644 --- a/include/SDL/SDL_syswm.h +++ b/include/SDL/SDL_syswm.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_thread.h b/include/SDL/SDL_thread.h index b5c94e732..dca94836a 100644 --- a/include/SDL/SDL_thread.h +++ b/include/SDL/SDL_thread.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_timer.h b/include/SDL/SDL_timer.h index a1c07e365..611eb5866 100644 --- a/include/SDL/SDL_timer.h +++ b/include/SDL/SDL_timer.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_types.h b/include/SDL/SDL_types.h index d597c9fdd..3db709c2a 100644 --- a/include/SDL/SDL_types.h +++ b/include/SDL/SDL_types.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_version.h b/include/SDL/SDL_version.h index da2eda36e..6e198bd92 100644 --- a/include/SDL/SDL_version.h +++ b/include/SDL/SDL_version.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_video.h b/include/SDL/SDL_video.h index b67cbe97e..409764d14 100644 --- a/include/SDL/SDL_video.h +++ b/include/SDL/SDL_video.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/begin_code.h b/include/SDL/begin_code.h index f44c36069..db140993e 100644 --- a/include/SDL/begin_code.h +++ b/include/SDL/begin_code.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/close_code.h b/include/SDL/close_code.h index 769cc5634..bdcde99b4 100644 --- a/include/SDL/close_code.h +++ b/include/SDL/close_code.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 331e962b2..31fd039ef 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/SDL12_compat_objc.m b/src/SDL12_compat_objc.m index ab7b56eec..8f4228874 100644 --- a/src/SDL12_compat_objc.m +++ b/src/SDL12_compat_objc.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/SDL20_include_wrapper.h b/src/SDL20_include_wrapper.h index 50aa440a8..32d24b137 100644 --- a/src/SDL20_include_wrapper.h +++ b/src/SDL20_include_wrapper.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/SDL20_syms.h b/src/SDL20_syms.h index 1fc50b0f9..f11de4589 100644 --- a/src/SDL20_syms.h +++ b/src/SDL20_syms.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/default_cursor.h b/src/default_cursor.h index 4e449059c..9c93666d3 100644 --- a/src/default_cursor.h +++ b/src/default_cursor.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/version.rc b/src/version.rc index adccff915..cb670e1b9 100644 --- a/src/version.rc +++ b/src/version.rc @@ -19,7 +19,7 @@ BEGIN VALUE "FileDescription", "SDL\0" VALUE "FileVersion", "1, 2, 69, 0\0" VALUE "InternalName", "SDL\0" - VALUE "LegalCopyright", "Copyright (C) 2024 Sam Lantinga\0" + VALUE "LegalCopyright", "Copyright (C) 2025 Sam Lantinga\0" VALUE "OriginalFilename", "SDL.dll\0" VALUE "ProductName", "Simple DirectMedia Layer 1.2 wrapper\0" VALUE "ProductVersion", "1, 2, 69, 0\0" diff --git a/src/x86_msvc.h b/src/x86_msvc.h index 4e88e4fdb..a25f5be26 100644 --- a/src/x86_msvc.h +++ b/src/x86_msvc.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages From 98111f0af8bd99cd2f3f51c9e8d12e9f5ac75c6e Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sun, 26 Oct 2025 12:41:14 -0700 Subject: [PATCH 558/606] Update relative mouse mode after changing fullscreen state Fixes https://github.com/libsdl-org/sdl12-compat/issues/301 --- src/SDL12_compat.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 31fd039ef..2654927ac 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -7698,10 +7698,8 @@ UpdateRelativeMouseMode(void) /* in SDL 1.2, hiding+grabbing the cursor was like SDL2's relative mouse mode. */ if (VideoWindow20) { const SDL_bool enable = (VideoWindowGrabbed && VideoCursorHidden) ? SDL_TRUE : SDL_FALSE; - if (MouseInputIsRelative != enable) { - MouseInputIsRelative = enable; - SDL20_SetRelativeMouseMode(MouseInputIsRelative); - } + MouseInputIsRelative = enable; + SDL20_SetRelativeMouseMode(MouseInputIsRelative); } } @@ -7712,11 +7710,9 @@ SDL_ShowCursor(int toggle) if (toggle >= 0) { const SDL_bool wanthide = (toggle == 0) ? SDL_TRUE : SDL_FALSE; - if (VideoCursorHidden != wanthide) { - SDL20_ShowCursor(wanthide ? 0 : 1); - VideoCursorHidden = wanthide; - UpdateRelativeMouseMode(); - } + SDL20_ShowCursor(wanthide ? 0 : 1); + VideoCursorHidden = wanthide; + UpdateRelativeMouseMode(); } return retval; } @@ -7725,9 +7721,9 @@ static void UpdateInputGrab(void) { /* SDL 1.2 always grabbed input if the video mode was fullscreen. */ - const SDL_bool isfullscreen = (VideoSurface12 && VideoSurface12->surface20 && (VideoSurface12->flags & SDL12_FULLSCREEN)) ? SDL_TRUE : SDL_FALSE; - const SDL_bool wantgrab = (VideoWindowGrabWanted || isfullscreen); if (VideoWindow20) { + const SDL_bool isfullscreen = (VideoSurface12 && VideoSurface12->surface20 && (VideoSurface12->flags & SDL12_FULLSCREEN)) ? SDL_TRUE : SDL_FALSE; + const SDL_bool wantgrab = (VideoWindowGrabWanted || isfullscreen); SDL20_SetWindowGrab(VideoWindow20, wantgrab); VideoWindowGrabbed = wantgrab; UpdateRelativeMouseMode(); From 20ab1608972b20f872fbe1b3647ac09b59f38654 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sun, 26 Oct 2025 13:29:14 -0700 Subject: [PATCH 559/606] Added GitHub release workflow --- .github/workflows/release.yml | 631 +++++++ CMakeLists.txt | 4 +- build-scripts/build-release.py | 1556 +++++++++++++++++ build-scripts/create-release.py | 45 + build-scripts/pkg-support/msvc/INSTALL.md | 11 + build-scripts/pkg-support/msvc/README.md | 21 + .../pkg-support/msvc/x64/INSTALL.md.in | 7 + .../pkg-support/msvc/x86/INSTALL.md.in | 7 + build-scripts/release-info.json | 87 + build-scripts/test-versioning.sh | 101 ++ .../update-version.sh | 2 + 11 files changed, 2469 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/release.yml create mode 100755 build-scripts/build-release.py create mode 100755 build-scripts/create-release.py create mode 100644 build-scripts/pkg-support/msvc/INSTALL.md create mode 100644 build-scripts/pkg-support/msvc/README.md create mode 100644 build-scripts/pkg-support/msvc/x64/INSTALL.md.in create mode 100644 build-scripts/pkg-support/msvc/x86/INSTALL.md.in create mode 100644 build-scripts/release-info.json create mode 100755 build-scripts/test-versioning.sh rename update_version.sh => build-scripts/update-version.sh (98%) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 000000000..889fbc02b --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,631 @@ +name: 'release' +run-name: 'Create sdl12-compat release artifacts for ${{ inputs.commit }}' + +on: + workflow_dispatch: + inputs: + commit: + description: 'Commit of sdl12-compat' + required: true + +jobs: + + src: + runs-on: ubuntu-latest + outputs: + project: ${{ steps.releaser.outputs.project }} + version: ${{ steps.releaser.outputs.version }} + src-tar-gz: ${{ steps.releaser.outputs.src-tar-gz }} + src-tar-xz: ${{ steps.releaser.outputs.src-tar-xz }} + src-zip: ${{ steps.releaser.outputs.src-zip }} + steps: + - name: 'Set up Python' + uses: actions/setup-python@v5 + with: + python-version: '3.11' + - name: 'Fetch build-release.py' + uses: actions/checkout@v4 + with: + ref: ${{ inputs.commit }} + sparse-checkout: 'build-scripts/build-release.py' + - name: 'Set up SDL sources' + uses: actions/checkout@v4 + with: + ref: ${{ inputs.commit }} + path: 'SDL' + fetch-depth: 0 + - name: 'Build Source archive' + id: releaser + shell: bash + env: + GH_TOKEN: ${{ github.token }} + run: | + python build-scripts/build-release.py \ + --actions source \ + --commit ${{ inputs.commit }} \ + --root "${{ github.workspace }}/SDL" \ + --github \ + --debug + - name: 'Store source archives' + uses: actions/upload-artifact@v4 + with: + name: sources + path: '${{ github.workspace}}/dist' + - name: 'Generate summary' + run: | + echo "Run the following commands to download all artifacts:" >> $GITHUB_STEP_SUMMARY + echo '```' >> $GITHUB_STEP_SUMMARY + echo "mkdir -p /tmp/${{ steps.releaser.outputs.project }}-${{ steps.releaser.outputs.version }}" >> $GITHUB_STEP_SUMMARY + echo "cd /tmp/${{ steps.releaser.outputs.project }}-${{ steps.releaser.outputs.version }}" >> $GITHUB_STEP_SUMMARY + echo "gh run -R ${{ github.repository }} download ${{ github.run_id }}" >> $GITHUB_STEP_SUMMARY + echo '```' >> $GITHUB_STEP_SUMMARY + + linux-verify: + needs: [src] + runs-on: ubuntu-latest + steps: + - name: 'Set up Python' + uses: actions/setup-python@v5 + with: + python-version: '3.11' + - name: 'Download source archives' + uses: actions/download-artifact@v4 + with: + name: sources + path: '/tmp' + - name: 'Unzip ${{ needs.src.outputs.src-zip }}' + id: zip + run: | + set -e + mkdir /tmp/zipdir + cd /tmp/zipdir + unzip "/tmp/${{ needs.src.outputs.src-zip }}" + echo "path=/tmp/zipdir/${{ needs.src.outputs.project }}-${{ needs.src.outputs.version }}" >>$GITHUB_OUTPUT + - name: 'Untar ${{ needs.src.outputs.src-tar-gz }}' + id: tar + run: | + set -e + mkdir -p /tmp/tardir + tar -C /tmp/tardir -v -x -f "/tmp/${{ needs.src.outputs.src-tar-gz }}" + echo "path=/tmp/tardir/${{ needs.src.outputs.project }}-${{ needs.src.outputs.version }}" >>$GITHUB_OUTPUT + - name: 'Compare contents of ${{ needs.src.outputs.src-zip }} and ${{ needs.src.outputs.src-tar-gz }}' + run: | + set -e + diff "${{ steps.zip.outputs.path }}" "${{ steps.tar.outputs.path }}" + - name: 'Test versioning' + shell: bash + run: | + ${{ steps.tar.outputs.path }}/build-scripts/test-versioning.sh + - name: 'Fetch build-release.py' + uses: actions/checkout@v4 + with: + ref: ${{ inputs.commit }} + sparse-checkout: | + build-scripts/build-release.py + .github/actions/setup-ninja/action.yml + - name: 'Download dependencies' + id: deps + env: + GH_TOKEN: ${{ github.token }} + run: | + python build-scripts/build-release.py \ + --actions download \ + --commit ${{ inputs.commit }} \ + --root "${{ steps.tar.outputs.path }}" \ + --github \ + --debug + - name: 'Install Linux dependencies' + run: | + sudo apt-get update -y + sudo apt-get install -y \ + gnome-desktop-testing libasound2-dev libpulse-dev libaudio-dev libjack-dev libsndio-dev \ + libusb-1.0-0-dev libx11-dev libxext-dev libxrandr-dev libxcursor-dev libxfixes-dev libxi-dev \ + libxss-dev libwayland-dev libxkbcommon-dev libdrm-dev libgbm-dev libgl1-mesa-dev libgles2-mesa-dev \ + libegl1-mesa-dev libdbus-1-dev libibus-1.0-dev libudev-dev fcitx-libs-dev + - name: 'Extract dependencies, build and install them' + id: deps-build + run: | + tar -C /tmp -v -x -f "${{ steps.deps.outputs.dep-path }}/SDL3-${{ steps.deps.outputs.dep-sdl-version }}.tar.gz" + cmake -S /tmp/SDL3-${{ steps.deps.outputs.dep-sdl-version }} -B /tmp/SDL-build -DSDL_UNIX_CONSOLE_BUILD=ON -DCMAKE_INSTALL_PREFIX=/tmp/deps-prefix + cmake --build /tmp/SDL-build + cmake --install /tmp/SDL-build + echo "path=/tmp/deps-prefix" >>$GITHUB_OUTPUT + - name: Set up ninja + uses: ./.github/actions/setup-ninja + - name: 'CMake (configure + build)' + run: | + cmake \ + -GNinja \ + -S ${{ steps.tar.outputs.path }} \ + -B /tmp/build \ + -DCMAKE_PREFIX_PATH="${{ steps.deps-build.outputs.path }}" + cmake --build /tmp/build --verbose + # ctest --test-dir /tmp/build --no-tests=error --output-on-failure + +# dmg: +# needs: [src] +# runs-on: macos-latest +# outputs: +# dmg: ${{ steps.releaser.outputs.dmg }} +# steps: +# - name: 'Set up Python' +# uses: actions/setup-python@v5 +# with: +# python-version: '3.11' +# - name: 'Fetch build-release.py' +# uses: actions/checkout@v4 +# with: +# ref: ${{ inputs.commit }} +# sparse-checkout: 'build-scripts/build-release.py' +# - name: 'Install nasm' +# run: | +# brew install nasm +# - name: 'Download source archives' +# uses: actions/download-artifact@v4 +# with: +# name: sources +# path: '${{ github.workspace }}' +# - name: 'Untar ${{ needs.src.outputs.src-tar-gz }}' +# id: tar +# run: | +# mkdir -p "${{ github.workspace }}/tardir" +# tar -C "${{ github.workspace }}/tardir" -v -x -f "${{ github.workspace }}/${{ needs.src.outputs.src-tar-gz }}" +# echo "path=${{ github.workspace }}/tardir/${{ needs.src.outputs.project }}-${{ needs.src.outputs.version }}" >>$GITHUB_OUTPUT +# - name: 'Download external dependencies' +# run: | +# sh "${{ steps.tar.outputs.path }}/external/download.sh" --depth 1 +# - name: 'Build SDL3_ttf.dmg' +# id: releaser +# shell: bash +# env: +# GH_TOKEN: ${{ github.token }} +# run: | +# python build-scripts/build-release.py \ +# --actions dmg \ +# --commit ${{ inputs.commit }} \ +# --root "${{ steps.tar.outputs.path }}" \ +# --github \ +# --debug +# - name: 'Store DMG image file' +# uses: actions/upload-artifact@v4 +# with: +# name: dmg +# path: '${{ github.workspace }}/dist' +# +# dmg-verify: +# needs: [dmg, src] +# runs-on: macos-latest +# steps: +# - name: 'Set up Python' +# uses: actions/setup-python@v5 +# with: +# python-version: '3.11' +# - name: 'Fetch build-release.py' +# uses: actions/checkout@v4 +# with: +# ref: ${{ inputs.commit }} +# sparse-checkout: 'build-scripts/build-release.py' +# - name: 'Download source archives' +# uses: actions/download-artifact@v4 +# with: +# name: sources +# path: '${{ github.workspace }}' +# - name: 'Untar ${{ needs.src.outputs.src-tar-gz }}' +# id: src +# run: | +# mkdir -p /tmp/tardir +# tar -C /tmp/tardir -v -x -f "${{ github.workspace }}/${{ needs.src.outputs.src-tar-gz }}" +# echo "path=/tmp/tardir/${{ needs.src.outputs.project }}-${{ needs.src.outputs.version }}" >>$GITHUB_OUTPUT +# - name: 'Download dependencies' +# id: deps +# env: +# GH_TOKEN: ${{ github.token }} +# run: | +# python build-scripts/build-release.py \ +# --actions download \ +# --commit ${{ inputs.commit }} \ +# --root "${{ steps.src.outputs.path }}" \ +# --github \ +# --debug +# - name: 'Mount dependencies' +# id: deps-mount +# run: | +# hdiutil attach "${{ steps.deps.outputs.dep-path }}/SDL3-${{ steps.deps.outputs.dep-sdl-version }}.dmg" +# sdl_mount_pount="/Volumes/SDL3" +# if [ ! -d "$sdl_mount_pount/SDL3.xcframework" ]; then +# echo "Cannot find SDL3.xcframework!" +# exit 1 +# fi +# echo "path=${sdl_mount_pount}" >>$GITHUB_OUTPUT +# - name: 'Download ${{ needs.dmg.outputs.dmg }}' +# uses: actions/download-artifact@v4 +# with: +# name: dmg +# path: '${{ github.workspace }}' +# - name: 'Mount ${{ needs.dmg.outputs.dmg }}' +# id: mount +# run: | +# hdiutil attach '${{ github.workspace }}/${{ needs.dmg.outputs.dmg }}' +# mount_point="/Volumes/${{ needs.src.outputs.project }}" +# if [ ! -d "$mount_point/${{ needs.src.outputs.project }}.xcframework" ]; then +# echo "Cannot find ${{ needs.src.outputs.project }}.xcframework!" +# exit 1 +# fi +# echo "mount-point=${mount_point}">>$GITHUB_OUTPUT +# - name: 'Verify presence of optional frameworks' +# run: | +# OPTIONAL_FRAMEWORKS="gme opus wavpack xmp" +# rc=0 +# for opt in $OPTIONAL_FRAMEWORKS; do +# fw_path="${{ steps.mount.outputs.mount-point }}/optional/${opt}.xcframework" +# if [ -d "${fw_path}" ]; then +# echo "$fw_path OK" +# else +# echo "$fw_path MISSING" +# rc=1 +# fi +# done +# exit $rc +# - name: 'CMake (configure + build) Darwin' +# run: | +# set -e +# cmake -S "${{ steps.src.outputs.path }}/cmake/test" \ +# -DTEST_SHARED=TRUE \ +# -DTEST_SHARED=TRUE \ +# -DTEST_STATIC=FALSE \ +# -DCMAKE_PREFIX_PATH="${{ steps.mount.outputs.mount-point }};${{ steps.deps-mount.outputs.path }}" \ +# -DCMAKE_SYSTEM_NAME=Darwin \ +# -DCMAKE_OSX_ARCHITECTURES="arm64;x86_64" \ +# -Werror=dev \ +# -B build_darwin +# cmake --build build_darwin --config Release --verbose +# +# - name: 'CMake (configure + build) iOS' +# run: | +# cmake -S "${{ steps.src.outputs.path }}/cmake/test" \ +# -DTEST_SHARED=TRUE \ +# -DTEST_STATIC=FALSE \ +# -DCMAKE_PREFIX_PATH="${{ steps.mount.outputs.mount-point }};${{ steps.deps-mount.outputs.path }}" \ +# -DCMAKE_SYSTEM_NAME=iOS \ +# -DCMAKE_OSX_ARCHITECTURES="arm64" \ +# -Werror=dev \ +# -B build_ios +# cmake --build build_ios --config Release --verbose +# - name: 'CMake (configure + build) tvOS' +# run: | +# cmake -S "${{ steps.src.outputs.path }}/cmake/test" \ +# -DTEST_SHARED=TRUE \ +# -DTEST_STATIC=FALSE \ +# -DCMAKE_PREFIX_PATH="${{ steps.mount.outputs.mount-point }};${{ steps.deps-mount.outputs.path }}" \ +# -DCMAKE_SYSTEM_NAME=tvOS \ +# -DCMAKE_OSX_ARCHITECTURES="arm64" \ +# -Werror=dev \ +# -B build_tvos +# cmake --build build_tvos --config Release --verbose +# - name: 'CMake (configure + build) iOS simulator' +# run: | +# sysroot=$(xcodebuild -version -sdk iphonesimulator Path) +# echo "sysroot=$sysroot" +# cmake -S "${{ steps.src.outputs.path }}/cmake/test" \ +# -DTEST_SHARED=TRUE \ +# -DTEST_STATIC=FALSE \ +# -DCMAKE_PREFIX_PATH="${{ steps.mount.outputs.mount-point }};${{ steps.deps-mount.outputs.path }}" \ +# -DCMAKE_SYSTEM_NAME=iOS \ +# -DCMAKE_OSX_ARCHITECTURES="arm64;x86_64" \ +# -DCMAKE_OSX_SYSROOT="${sysroot}" \ +# -Werror=dev \ +# -B build_ios_simulator +# cmake --build build_ios_simulator --config Release --verbose +# - name: 'CMake (configure + build) tvOS simulator' +# run: | +# sysroot=$(xcodebuild -version -sdk appletvsimulator Path) +# echo "sysroot=$sysroot" +# cmake -S "${{ steps.src.outputs.path }}/cmake/test" \ +# -DTEST_SHARED=TRUE \ +# -DTEST_STATIC=FALSE \ +# -DCMAKE_PREFIX_PATH="${{ steps.mount.outputs.mount-point }};${{ steps.deps-mount.outputs.path }}" \ +# -DCMAKE_SYSTEM_NAME=tvOS \ +# -DCMAKE_OSX_ARCHITECTURES="arm64;x86_64" \ +# -DCMAKE_OSX_SYSROOT="${sysroot}" \ +# -Werror=dev \ +# -B build_tvos_simulator +# cmake --build build_tvos_simulator --config Release --verbose + msvc: + needs: [src] + runs-on: windows-2025 + outputs: + VC-x86: ${{ steps.releaser.outputs.VC-x86 }} + VC-x64: ${{ steps.releaser.outputs.VC-x64 }} + VC-devel: ${{ steps.releaser.outputs.VC-devel }} + steps: + - name: 'Set up Python' + uses: actions/setup-python@v5 + with: + python-version: '3.11' + - name: 'Fetch build-release.py' + uses: actions/checkout@v4 + with: + ref: ${{ inputs.commit }} + sparse-checkout: 'build-scripts/build-release.py' + - name: 'Download source archives' + uses: actions/download-artifact@v4 + with: + name: sources + path: '${{ github.workspace }}' + - name: 'Unzip ${{ needs.src.outputs.src-zip }}' + id: zip + run: | + New-Item C:\temp -ItemType Directory -ErrorAction SilentlyContinue + cd C:\temp + unzip "${{ github.workspace }}/${{ needs.src.outputs.src-zip }}" + echo "path=C:\temp\${{ needs.src.outputs.project }}-${{ needs.src.outputs.version }}" >>$Env:GITHUB_OUTPUT +# - name: 'Download external dependencies' +# run: | +# ${{ steps.zip.outputs.path }}/external/Get-GitModules.ps1 + - name: 'Build MSVC binary archives' + id: releaser + env: + GH_TOKEN: ${{ github.token }} + run: | + python build-scripts/build-release.py ` + --actions download msvc ` + --commit ${{ inputs.commit }} ` + --root "${{ steps.zip.outputs.path }}" ` + --github ` + --debug + - name: 'Store MSVC archives' + uses: actions/upload-artifact@v4 + with: + name: msvc + path: '${{ github.workspace }}/dist' + + msvc-verify: + needs: [msvc, src] + runs-on: windows-latest + steps: + - name: 'Fetch .github/actions/setup-ninja/action.yml' + uses: actions/checkout@v4 + with: + ref: ${{ inputs.commit }} + sparse-checkout: | + .github/actions/setup-ninja/action.yml + build-scripts/build-release.py + - name: 'Set up Python' + uses: actions/setup-python@v5 + with: + python-version: '3.11' + - name: Set up ninja + uses: ./.github/actions/setup-ninja + - name: 'Download source archives' + uses: actions/download-artifact@v4 + with: + name: sources + path: '${{ github.workspace }}' + - name: 'Unzip ${{ needs.src.outputs.src-zip }}' + id: src + run: | + mkdir '${{ github.workspace }}/sources' + cd '${{ github.workspace }}/sources' + unzip "${{ github.workspace }}/${{ needs.src.outputs.src-zip }}" + echo "path=${{ github.workspace }}/sources/${{ needs.src.outputs.project }}-${{ needs.src.outputs.version }}" >>$env:GITHUB_OUTPUT + - name: 'Download dependencies' + id: deps + env: + GH_TOKEN: ${{ github.token }} + run: | + python build-scripts/build-release.py ` + --actions download ` + --commit ${{ inputs.commit }} ` + --root "${{ steps.src.outputs.path }}" ` + --github ` + --debug + - name: 'Extract dependencies' + id: deps-extract + run: | + mkdir '${{ github.workspace }}/deps-vc' + cd '${{ github.workspace }}/deps-vc' + unzip "${{ steps.deps.outputs.dep-path }}/SDL3-devel-${{ steps.deps.outputs.dep-sdl-version }}-VC.zip" + echo "path=${{ github.workspace }}/deps-vc" >>$env:GITHUB_OUTPUT + - name: 'Download MSVC binaries' + uses: actions/download-artifact@v4 + with: + name: msvc + path: '${{ github.workspace }}' + - name: 'Unzip ${{ needs.msvc.outputs.VC-devel }}' + id: bin + run: | + mkdir '${{ github.workspace }}/vc' + cd '${{ github.workspace }}/vc' + unzip "${{ github.workspace }}/${{ needs.msvc.outputs.VC-devel }}" + echo "path=${{ github.workspace }}/vc/${{ needs.src.outputs.project }}-${{ needs.src.outputs.version }}" >>$env:GITHUB_OUTPUT + - name: 'Configure vcvars x86' + uses: ilammy/msvc-dev-cmd@v1 + with: + arch: x64_x86 + - name: 'CMake (configure + build + tests) x86' + run: | + cmake -S "${{ steps.src.outputs.path }}/cmake/test" ` + -B build_x86 ` + -GNinja ` + -DCMAKE_BUILD_TYPE=Debug ` + -Werror=dev ` + -DTEST_SHARED=TRUE ` + -DTEST_STATIC=FALSE ` + -DCMAKE_SUPPRESS_REGENERATION=TRUE ` + -DCMAKE_PREFIX_PATH="${{ steps.bin.outputs.path }};${{ steps.deps-extract.outputs.path }}" + Start-Sleep -Seconds 2 + cmake --build build_x86 --config Release --verbose + - name: 'Configure vcvars x64' + uses: ilammy/msvc-dev-cmd@v1 + with: + arch: x64 + - name: 'CMake (configure + build + tests) x64' + run: | + cmake -S "${{ steps.src.outputs.path }}/cmake/test" ` + -B build_x64 ` + -GNinja ` + -DCMAKE_BUILD_TYPE=Debug ` + -Werror=dev ` + -DTEST_SHARED=TRUE ` + -DTEST_STATIC=FALSE ` + -DCMAKE_SUPPRESS_REGENERATION=TRUE ` + -DCMAKE_PREFIX_PATH="${{ steps.bin.outputs.path }};${{ steps.deps-extract.outputs.path }}" + Start-Sleep -Seconds 2 + cmake --build build_x64 --config Release --verbose +# - name: 'Configure vcvars arm64' +# uses: ilammy/msvc-dev-cmd@v1 +# with: +# arch: x64_arm64 +# - name: 'CMake (configure + build + tests) arm64' +# run: | +# cmake -S "${{ steps.src.outputs.path }}/cmake/test" ` +# -B build_arm64 ` +# -GNinja ` +# -DCMAKE_BUILD_TYPE=Debug ` +# -Werror=dev ` +# -DTEST_SHARED=TRUE ` +# -DTEST_STATIC=FALSE ` +# -DCMAKE_SUPPRESS_REGENERATION=TRUE ` +# -DCMAKE_PREFIX_PATH="${{ steps.bin.outputs.path }};${{ steps.deps-extract.outputs.path }}" +# Start-Sleep -Seconds 2 +# cmake --build build_arm64 --config Release --verbose + +# mingw: +# needs: [src] +# runs-on: ubuntu-24.04 # FIXME: current ubuntu-latest ships an outdated mingw, replace with ubuntu-latest once 24.04 becomes the new default +# outputs: +# mingw-devel-tar-gz: ${{ steps.releaser.outputs.mingw-devel-tar-gz }} +# mingw-devel-tar-xz: ${{ steps.releaser.outputs.mingw-devel-tar-xz }} +# steps: +# - name: 'Set up Python' +# uses: actions/setup-python@v5 +# with: +# python-version: '3.11' +# - name: 'Fetch build-release.py' +# uses: actions/checkout@v4 +# with: +# ref: ${{ inputs.commit }} +# sparse-checkout: 'build-scripts/build-release.py' +# - name: 'Install Mingw toolchain' +# run: | +# sudo apt-get update -y +# sudo apt-get install -y gcc-mingw-w64 g++-mingw-w64 ninja-build +# - name: 'Download source archives' +# uses: actions/download-artifact@v4 +# with: +# name: sources +# path: '${{ github.workspace }}' +# - name: 'Untar ${{ needs.src.outputs.src-tar-gz }}' +# id: tar +# run: | +# mkdir -p /tmp/tardir +# tar -C /tmp/tardir -v -x -f "${{ github.workspace }}/${{ needs.src.outputs.src-tar-gz }}" +# echo "path=/tmp/tardir/${{ needs.src.outputs.project }}-${{ needs.src.outputs.version }}" >>$GITHUB_OUTPUT +# - name: 'Download external dependencies' +# run: | +# sh "${{ steps.tar.outputs.path }}/external/download.sh" --depth 1 +# - name: 'Build MinGW binary archives' +# id: releaser +# env: +# GH_TOKEN: ${{ github.token }} +# run: | +# python build-scripts/build-release.py \ +# --actions download mingw \ +# --commit ${{ inputs.commit }} \ +# --root "${{ steps.tar.outputs.path }}" \ +# --github \ +# --debug +# - name: 'Store MinGW archives' +# uses: actions/upload-artifact@v4 +# with: +# name: mingw +# path: '${{ github.workspace }}/dist' +# +# mingw-verify: +# needs: [mingw, src] +# runs-on: ubuntu-latest +# steps: +# - name: 'Set up Python' +# uses: actions/setup-python@v5 +# with: +# python-version: '3.11' +# - name: 'Fetch build-release.py' +# uses: actions/checkout@v4 +# with: +# ref: ${{ inputs.commit }} +# sparse-checkout: 'build-scripts/build-release.py' +# - name: 'Install Mingw toolchain' +# run: | +# sudo apt-get update -y +# sudo apt-get install -y gcc-mingw-w64 g++-mingw-w64 ninja-build +# - name: 'Download source archives' +# uses: actions/download-artifact@v4 +# with: +# name: sources +# path: '${{ github.workspace }}' +# - name: 'Untar ${{ needs.src.outputs.src-tar-gz }}' +# id: src +# run: | +# mkdir -p /tmp/tardir +# tar -C /tmp/tardir -v -x -f "${{ github.workspace }}/${{ needs.src.outputs.src-tar-gz }}" +# echo "path=/tmp/tardir/${{ needs.src.outputs.project }}-${{ needs.src.outputs.version }}" >>$GITHUB_OUTPUT +# - name: 'Download dependencies' +# id: deps +# env: +# GH_TOKEN: ${{ github.token }} +# run: | +# python build-scripts/build-release.py \ +# --actions download \ +# --commit ${{ inputs.commit }} \ +# --root "${{ steps.src.outputs.path }}" \ +# --github \ +# --debug +# - name: 'Untar and install dependencies' +# id: deps-extract +# run: | +# mkdir -p /tmp/deps-mingw/cmake +# mkdir -p /tmp/deps-mingw/i686-w64-mingw32 +# mkdir -p /tmp/deps-mingw/x86_64-w64-mingw32 +# +# mkdir -p /tmp/deps-mingw-extract/sdl3 +# tar -C /tmp/deps-mingw-extract/sdl3 -v -x -f "${{ steps.deps.outputs.dep-path }}/SDL3-devel-${{ steps.deps.outputs.dep-sdl-version }}-mingw.tar.gz" +# make -C /tmp/deps-mingw-extract/sdl3/SDL3-${{ steps.deps.outputs.dep-sdl-version }} install-all DESTDIR=/tmp/deps-mingw +# +# # FIXME: this should be fixed in SDL3 releases after 3.1.3 +# mkdir -p /tmp/deps-mingw/cmake +# cp -rv /tmp/deps-mingw-extract/sdl3/SDL3-${{ steps.deps.outputs.dep-sdl-version }}/cmake/* /tmp/deps-mingw/cmake +# - name: 'Download MinGW binaries' +# uses: actions/download-artifact@v4 +# with: +# name: mingw +# path: '${{ github.workspace }}' +# - name: 'Untar and install ${{ needs.mingw.outputs.mingw-devel-tar-gz }}' +# id: bin +# run: | +# mkdir -p /tmp/mingw-tardir +# tar -C /tmp/mingw-tardir -v -x -f "${{ github.workspace }}/${{ needs.mingw.outputs.mingw-devel-tar-gz }}" +# make -C /tmp/mingw-tardir/${{ needs.src.outputs.project }}-${{ needs.src.outputs.version }} install-all DESTDIR=/tmp/deps-mingw +# - name: 'CMake (configure + build) i686' +# run: | +# set -e +# cmake -S "${{ steps.src.outputs.path }}/cmake/test" \ +# -DCMAKE_BUILD_TYPE="Release" \ +# -DTEST_SHARED=TRUE \ +# -DTEST_STATIC=TRUE \ +# -DCMAKE_PREFIX_PATH="/tmp/deps-mingw" \ +# -DCMAKE_TOOLCHAIN_FILE="${{ steps.src.outputs.path }}/build-scripts/cmake-toolchain-mingw64-i686.cmake" \ +# -Werror=dev \ +# -B build_x86 +# cmake --build build_x86 --config Release --verbose +# - name: 'CMake (configure + build) x86_64' +# run: | +# set -e +# cmake -S "${{ steps.src.outputs.path }}/cmake/test" \ +# -DCMAKE_BUILD_TYPE="Release" \ +# -DTEST_SHARED=TRUE \ +# -DTEST_STATIC=TRUE \ +# -DCMAKE_PREFIX_PATH="/tmp/deps-mingw" \ +# -DCMAKE_TOOLCHAIN_FILE="${{ steps.src.outputs.path }}/build-scripts/cmake-toolchain-mingw64-x86_64.cmake" \ +# -Werror=dev \ +# -B build_x64 +# cmake --build build_x64 --config Release --verbose diff --git a/CMakeLists.txt b/CMakeLists.txt index 45f346d2b..6094ec958 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,9 +3,7 @@ # cmake -DSDL2_INCLUDE_DIR=/opt/SDL2/include/SDL2 [other stuff] cmake_minimum_required(VERSION 3.0.0...4.0) -project(sdl12_compat - VERSION 1.2.69 - LANGUAGES C) +project(sdl12_compat VERSION 1.2.69 LANGUAGES C) option(SDL12TESTS "Enable to build SDL-1.2 test programs" ON) option(SDL12DEVEL "Enable installing SDL-1.2 development headers" ON) diff --git a/build-scripts/build-release.py b/build-scripts/build-release.py new file mode 100755 index 000000000..f3faa06c3 --- /dev/null +++ b/build-scripts/build-release.py @@ -0,0 +1,1556 @@ +#!/usr/bin/env python3 + +""" +This script is shared between SDL2, SDL3, and all satellite libraries. +Don't specialize this script for doing project-specific modifications. +Rather, modify release-info.json. +""" + +import argparse +import collections +import dataclasses +from collections.abc import Callable +import contextlib +import datetime +import fnmatch +import glob +import io +import json +import logging +import multiprocessing +import os +from pathlib import Path +import platform +import re +import shlex +import shutil +import subprocess +import sys +import tarfile +import tempfile +import textwrap +import typing +import zipfile + + +logger = logging.getLogger(__name__) +GIT_HASH_FILENAME = ".git-hash" +REVISION_TXT = "REVISION.txt" + +RE_ILLEGAL_MINGW_LIBRARIES = re.compile(r"(?:lib)?(?:gcc|(?:std)?c[+][+]|(?:win)?pthread).*", flags=re.I) + + +def safe_isotime_to_datetime(str_isotime: str) -> datetime.datetime: + try: + return datetime.datetime.fromisoformat(str_isotime) + except ValueError: + pass + logger.warning("Invalid iso time: %s", str_isotime) + if str_isotime[-6:-5] in ("+", "-"): + # Commits can have isotime with invalid timezone offset (e.g. "2021-07-04T20:01:40+32:00") + modified_str_isotime = str_isotime[:-6] + "+00:00" + try: + return datetime.datetime.fromisoformat(modified_str_isotime) + except ValueError: + pass + raise ValueError(f"Invalid isotime: {str_isotime}") + + +def arc_join(*parts: list[str]) -> str: + assert all(p[:1] != "/" and p[-1:] != "/" for p in parts), f"None of {parts} may start or end with '/'" + return "/".join(p for p in parts if p) + + +@dataclasses.dataclass(frozen=True) +class VsArchPlatformConfig: + arch: str + configuration: str + platform: str + + def extra_context(self): + return { + "ARCH": self.arch, + "CONFIGURATION": self.configuration, + "PLATFORM": self.platform, + } + + +@contextlib.contextmanager +def chdir(path): + original_cwd = os.getcwd() + try: + os.chdir(path) + yield + finally: + os.chdir(original_cwd) + + +class Executer: + def __init__(self, root: Path, dry: bool=False): + self.root = root + self.dry = dry + + def run(self, cmd, cwd=None, env=None): + logger.info("Executing args=%r", cmd) + sys.stdout.flush() + if not self.dry: + subprocess.check_call(cmd, cwd=cwd or self.root, env=env, text=True) + + def check_output(self, cmd, cwd=None, dry_out=None, env=None, text=True): + logger.info("Executing args=%r", cmd) + sys.stdout.flush() + if self.dry: + return dry_out + return subprocess.check_output(cmd, cwd=cwd or self.root, env=env, text=text) + + +class SectionPrinter: + @contextlib.contextmanager + def group(self, title: str): + print(f"{title}:") + yield + + +class GitHubSectionPrinter(SectionPrinter): + def __init__(self): + super().__init__() + self.in_group = False + + @contextlib.contextmanager + def group(self, title: str): + print(f"::group::{title}") + assert not self.in_group, "Can enter a group only once" + self.in_group = True + yield + self.in_group = False + print("::endgroup::") + + +class VisualStudio: + def __init__(self, executer: Executer, year: typing.Optional[str]=None): + self.executer = executer + self.vsdevcmd = self.find_vsdevcmd(year) + self.msbuild = self.find_msbuild() + + @property + def dry(self) -> bool: + return self.executer.dry + + VS_YEAR_TO_VERSION = { + "2022": 17, + "2019": 16, + "2017": 15, + "2015": 14, + "2013": 12, + } + + def find_vsdevcmd(self, year: typing.Optional[str]=None) -> typing.Optional[Path]: + vswhere_spec = ["-latest"] + if year is not None: + try: + version = self.VS_YEAR_TO_VERSION[year] + except KeyError: + logger.error("Invalid Visual Studio year") + return None + vswhere_spec.extend(["-version", f"[{version},{version+1})"]) + vswhere_cmd = ["vswhere"] + vswhere_spec + ["-property", "installationPath"] + vs_install_path = Path(self.executer.check_output(vswhere_cmd, dry_out="/tmp").strip()) + logger.info("VS install_path = %s", vs_install_path) + assert vs_install_path.is_dir(), "VS installation path does not exist" + vsdevcmd_path = vs_install_path / "Common7/Tools/vsdevcmd.bat" + logger.info("vsdevcmd path = %s", vsdevcmd_path) + if self.dry: + vsdevcmd_path.parent.mkdir(parents=True, exist_ok=True) + vsdevcmd_path.touch(exist_ok=True) + assert vsdevcmd_path.is_file(), "vsdevcmd.bat batch file does not exist" + return vsdevcmd_path + + def find_msbuild(self) -> typing.Optional[Path]: + vswhere_cmd = ["vswhere", "-latest", "-requires", "Microsoft.Component.MSBuild", "-find", r"MSBuild\**\Bin\MSBuild.exe"] + msbuild_path = Path(self.executer.check_output(vswhere_cmd, dry_out="/tmp/MSBuild.exe").strip()) + logger.info("MSBuild path = %s", msbuild_path) + if self.dry: + msbuild_path.parent.mkdir(parents=True, exist_ok=True) + msbuild_path.touch(exist_ok=True) + assert msbuild_path.is_file(), "MSBuild.exe does not exist" + return msbuild_path + + def build(self, arch_platform: VsArchPlatformConfig, projects: list[Path]): + assert projects, "Need at least one project to build" + + vsdev_cmd_str = f"\"{self.vsdevcmd}\" -arch={arch_platform.arch}" + msbuild_cmd_str = " && ".join([f"\"{self.msbuild}\" \"{project}\" /m /p:BuildInParallel=true /p:Platform={arch_platform.platform} /p:Configuration={arch_platform.configuration}" for project in projects]) + bat_contents = f"{vsdev_cmd_str} && {msbuild_cmd_str}\n" + bat_path = Path(tempfile.gettempdir()) / "cmd.bat" + with bat_path.open("w") as f: + f.write(bat_contents) + + logger.info("Running cmd.exe script (%s): %s", bat_path, bat_contents) + cmd = ["cmd.exe", "/D", "/E:ON", "/V:OFF", "/S", "/C", f"CALL {str(bat_path)}"] + self.executer.run(cmd) + + +class Archiver: + def __init__(self, zip_path: typing.Optional[Path]=None, tgz_path: typing.Optional[Path]=None, txz_path: typing.Optional[Path]=None): + self._zip_files = [] + self._tar_files = [] + self._added_files = set() + if zip_path: + self._zip_files.append(zipfile.ZipFile(zip_path, "w", compression=zipfile.ZIP_DEFLATED)) + if tgz_path: + self._tar_files.append(tarfile.open(tgz_path, "w:gz")) + if txz_path: + self._tar_files.append(tarfile.open(txz_path, "w:xz")) + + @property + def added_files(self) -> set[str]: + return self._added_files + + def add_file_data(self, arcpath: str, data: bytes, mode: int, time: datetime.datetime): + for zf in self._zip_files: + file_data_time = (time.year, time.month, time.day, time.hour, time.minute, time.second) + zip_info = zipfile.ZipInfo(filename=arcpath, date_time=file_data_time) + zip_info.external_attr = mode << 16 + zip_info.compress_type = zipfile.ZIP_DEFLATED + zf.writestr(zip_info, data=data) + for tf in self._tar_files: + tar_info = tarfile.TarInfo(arcpath) + tar_info.type = tarfile.REGTYPE + tar_info.mode = mode + tar_info.size = len(data) + tar_info.mtime = int(time.timestamp()) + tf.addfile(tar_info, fileobj=io.BytesIO(data)) + + self._added_files.add(arcpath) + + def add_symlink(self, arcpath: str, target: str, time: datetime.datetime, files_for_zip): + logger.debug("Adding symlink (target=%r) -> %s", target, arcpath) + for zf in self._zip_files: + file_data_time = (time.year, time.month, time.day, time.hour, time.minute, time.second) + for f in files_for_zip: + zip_info = zipfile.ZipInfo(filename=f["arcpath"], date_time=file_data_time) + zip_info.external_attr = f["mode"] << 16 + zip_info.compress_type = zipfile.ZIP_DEFLATED + zf.writestr(zip_info, data=f["data"]) + for tf in self._tar_files: + tar_info = tarfile.TarInfo(arcpath) + tar_info.type = tarfile.SYMTYPE + tar_info.mode = 0o777 + tar_info.mtime = int(time.timestamp()) + tar_info.linkname = target + tf.addfile(tar_info) + + self._added_files.update(f["arcpath"] for f in files_for_zip) + + def add_git_hash(self, arcdir: str, commit: str, time: datetime.datetime): + arcpath = arc_join(arcdir, GIT_HASH_FILENAME) + data = f"{commit}\n".encode() + self.add_file_data(arcpath=arcpath, data=data, mode=0o100644, time=time) + + def add_file_path(self, arcpath: str, path: Path): + assert path.is_file(), f"{path} should be a file" + logger.debug("Adding %s -> %s", path, arcpath) + for zf in self._zip_files: + zf.write(path, arcname=arcpath) + for tf in self._tar_files: + tf.add(path, arcname=arcpath) + + def add_file_directory(self, arcdirpath: str, dirpath: Path): + assert dirpath.is_dir() + if arcdirpath and arcdirpath[-1:] != "/": + arcdirpath += "/" + for f in dirpath.iterdir(): + if f.is_file(): + arcpath = f"{arcdirpath}{f.name}" + logger.debug("Adding %s to %s", f, arcpath) + self.add_file_path(arcpath=arcpath, path=f) + + def close(self): + # Archiver is intentionally made invalid after this function + del self._zip_files + self._zip_files = None + del self._tar_files + self._tar_files = None + + def __enter__(self): + return self + + def __exit__(self, type, value, traceback): + self.close() + + +class NodeInArchive: + def __init__(self, arcpath: str, path: typing.Optional[Path]=None, data: typing.Optional[bytes]=None, mode: typing.Optional[int]=None, symtarget: typing.Optional[str]=None, time: typing.Optional[datetime.datetime]=None, directory: bool=False): + self.arcpath = arcpath + self.path = path + self.data = data + self.mode = mode + self.symtarget = symtarget + self.time = time + self.directory = directory + + @classmethod + def from_fs(cls, arcpath: str, path: Path, mode: int=0o100644, time: typing.Optional[datetime.datetime]=None) -> "NodeInArchive": + if time is None: + time = datetime.datetime.fromtimestamp(os.stat(path).st_mtime) + return cls(arcpath=arcpath, path=path, mode=mode) + + @classmethod + def from_data(cls, arcpath: str, data: bytes, time: datetime.datetime) -> "NodeInArchive": + return cls(arcpath=arcpath, data=data, time=time, mode=0o100644) + + @classmethod + def from_text(cls, arcpath: str, text: str, time: datetime.datetime) -> "NodeInArchive": + return cls.from_data(arcpath=arcpath, data=text.encode(), time=time) + + @classmethod + def from_symlink(cls, arcpath: str, symtarget: str) -> "NodeInArchive": + return cls(arcpath=arcpath, symtarget=symtarget) + + @classmethod + def from_directory(cls, arcpath: str) -> "NodeInArchive": + return cls(arcpath=arcpath, directory=True) + + def __repr__(self) -> str: + return f"<{type(self).__name__}:arcpath={self.arcpath},path='{str(self.path)}',len(data)={len(self.data) if self.data else 'n/a'},directory={self.directory},symtarget={self.symtarget}>" + + +def configure_file(path: Path, context: dict[str, str]) -> bytes: + text = path.read_text() + return configure_text(text, context=context).encode() + + +def configure_text(text: str, context: dict[str, str]) -> str: + original_text = text + for txt, repl in context.items(): + text = text.replace(f"@<@{txt}@>@", repl) + success = all(thing not in text for thing in ("@<@", "@>@")) + if not success: + raise ValueError(f"Failed to configure {repr(original_text)}") + return text + + +def configure_text_list(text_list: list[str], context: dict[str, str]) -> list[str]: + return [configure_text(text=e, context=context) for e in text_list] + + +class ArchiveFileTree: + def __init__(self): + self._tree: dict[str, NodeInArchive] = {} + + def add_file(self, file: NodeInArchive): + self._tree[file.arcpath] = file + + def __iter__(self) -> typing.Iterable[NodeInArchive]: + yield from self._tree.values() + + def __contains__(self, value: str) -> bool: + return value in self._tree + + def get_latest_mod_time(self) -> datetime.datetime: + return max(item.time for item in self._tree.values() if item.time) + + def add_to_archiver(self, archive_base: str, archiver: Archiver): + remaining_symlinks = set() + added_files = dict() + + def calculate_symlink_target(s: NodeInArchive) -> str: + dest_dir = os.path.dirname(s.arcpath) + if dest_dir: + dest_dir += "/" + target = dest_dir + s.symtarget + while True: + new_target, n = re.subn(r"([^/]+/+[.]{2}/)", "", target) + target = new_target + if not n: + break + return target + + # Add files in first pass + for arcpath, node in self._tree.items(): + assert node is not None, f"{arcpath} -> node" + if node.data is not None: + archiver.add_file_data(arcpath=arc_join(archive_base, arcpath), data=node.data, time=node.time, mode=node.mode) + assert node.arcpath is not None, f"{node=}" + added_files[node.arcpath] = node + elif node.path is not None: + archiver.add_file_path(arcpath=arc_join(archive_base, arcpath), path=node.path) + assert node.arcpath is not None, f"{node=}" + added_files[node.arcpath] = node + elif node.symtarget is not None: + remaining_symlinks.add(node) + elif node.directory: + pass + else: + raise ValueError(f"Invalid Archive Node: {repr(node)}") + + assert None not in added_files + + # Resolve symlinks in second pass: zipfile does not support symlinks, so add files to zip archive + while True: + if not remaining_symlinks: + break + symlinks_this_time = set() + extra_added_files = {} + for symlink in remaining_symlinks: + symlink_files_for_zip = {} + symlink_target_path = calculate_symlink_target(symlink) + if symlink_target_path in added_files: + symlink_files_for_zip[symlink.arcpath] = added_files[symlink_target_path] + else: + symlink_target_path_slash = symlink_target_path + "/" + for added_file in added_files: + if added_file.startswith(symlink_target_path_slash): + path_in_symlink = symlink.arcpath + "/" + added_file.removeprefix(symlink_target_path_slash) + symlink_files_for_zip[path_in_symlink] = added_files[added_file] + if symlink_files_for_zip: + symlinks_this_time.add(symlink) + extra_added_files.update(symlink_files_for_zip) + files_for_zip = [{"arcpath": f"{archive_base}/{sym_path}", "data": sym_info.data, "mode": sym_info.mode} for sym_path, sym_info in symlink_files_for_zip.items()] + archiver.add_symlink(arcpath=f"{archive_base}/{symlink.arcpath}", target=symlink.symtarget, time=symlink.time, files_for_zip=files_for_zip) + # if not symlinks_this_time: + # logger.info("files added: %r", set(path for path in added_files.keys())) + assert symlinks_this_time, f"No targets found for symlinks: {remaining_symlinks}" + remaining_symlinks.difference_update(symlinks_this_time) + added_files.update(extra_added_files) + + def add_directory_tree(self, arc_dir: str, path: Path, time: datetime.datetime): + assert path.is_dir() + for files_dir, _, filenames in os.walk(path): + files_dir_path = Path(files_dir) + rel_files_path = files_dir_path.relative_to(path) + for filename in filenames: + self.add_file(NodeInArchive.from_fs(arcpath=arc_join(arc_dir, str(rel_files_path), filename), path=files_dir_path / filename, time=time)) + + def _add_files_recursively(self, arc_dir: str, paths: list[Path], time: datetime.datetime): + logger.debug(f"_add_files_recursively({arc_dir=} {paths=})") + for path in paths: + arcpath = arc_join(arc_dir, path.name) + if path.is_file(): + logger.debug("Adding %s as %s", path, arcpath) + self.add_file(NodeInArchive.from_fs(arcpath=arcpath, path=path, time=time)) + elif path.is_dir(): + self._add_files_recursively(arc_dir=arc_join(arc_dir, path.name), paths=list(path.iterdir()), time=time) + else: + raise ValueError(f"Unsupported file type to add recursively: {path}") + + def add_file_mapping(self, arc_dir: str, file_mapping: dict[str, list[str]], file_mapping_root: Path, context: dict[str, str], time: datetime.datetime): + for meta_rel_destdir, meta_file_globs in file_mapping.items(): + rel_destdir = configure_text(meta_rel_destdir, context=context) + assert "@" not in rel_destdir, f"archive destination should not contain an @ after configuration ({repr(meta_rel_destdir)}->{repr(rel_destdir)})" + for meta_file_glob in meta_file_globs: + file_glob = configure_text(meta_file_glob, context=context) + assert "@" not in rel_destdir, f"archive glob should not contain an @ after configuration ({repr(meta_file_glob)}->{repr(file_glob)})" + if ":" in file_glob: + original_path, new_filename = file_glob.rsplit(":", 1) + assert ":" not in original_path, f"Too many ':' in {repr(file_glob)}" + assert "/" not in new_filename, f"New filename cannot contain a '/' in {repr(file_glob)}" + path = file_mapping_root / original_path + arcpath = arc_join(arc_dir, rel_destdir, new_filename) + if path.suffix == ".in": + data = configure_file(path, context=context) + logger.debug("Adding processed %s -> %s", path, arcpath) + self.add_file(NodeInArchive.from_data(arcpath=arcpath, data=data, time=time)) + else: + logger.debug("Adding %s -> %s", path, arcpath) + self.add_file(NodeInArchive.from_fs(arcpath=arcpath, path=path, time=time)) + else: + relative_file_paths = glob.glob(file_glob, root_dir=file_mapping_root) + assert relative_file_paths, f"Glob '{file_glob}' does not match any file" + self._add_files_recursively(arc_dir=arc_join(arc_dir, rel_destdir), paths=[file_mapping_root / p for p in relative_file_paths], time=time) + + +class SourceCollector: + # TreeItem = collections.namedtuple("TreeItem", ("path", "mode", "data", "symtarget", "directory", "time")) + def __init__(self, root: Path, commit: str, filter: typing.Optional[Callable[[str], bool]], executer: Executer): + self.root = root + self.commit = commit + self.filter = filter + self.executer = executer + + def get_archive_file_tree(self) -> ArchiveFileTree: + git_archive_args = ["git", "archive", "--format=tar.gz", self.commit, "-o", "/dev/stdout"] + logger.info("Executing args=%r", git_archive_args) + contents_tgz = subprocess.check_output(git_archive_args, cwd=self.root, text=False) + tar_archive = tarfile.open(fileobj=io.BytesIO(contents_tgz), mode="r:gz") + filenames = tuple(m.name for m in tar_archive if (m.isfile() or m.issym())) + + file_times = self._get_file_times(paths=filenames) + git_contents = ArchiveFileTree() + for ti in tar_archive: + if self.filter and not self.filter(ti.name): + continue + data = None + symtarget = None + directory = False + file_time = None + if ti.isfile(): + contents_file = tar_archive.extractfile(ti.name) + data = contents_file.read() + file_time = file_times[ti.name] + elif ti.issym(): + symtarget = ti.linkname + file_time = file_times[ti.name] + elif ti.isdir(): + directory = True + else: + raise ValueError(f"{ti.name}: unknown type") + node = NodeInArchive(arcpath=ti.name, data=data, mode=ti.mode, symtarget=symtarget, time=file_time, directory=directory) + git_contents.add_file(node) + return git_contents + + def _get_file_times(self, paths: tuple[str, ...]) -> dict[str, datetime.datetime]: + dry_out = textwrap.dedent("""\ + time=2024-03-14T15:40:25-07:00 + + M\tCMakeLists.txt + """) + git_log_out = self.executer.check_output(["git", "log", "--name-status", '--pretty=time=%cI', self.commit], dry_out=dry_out, cwd=self.root).splitlines(keepends=False) + current_time = None + set_paths = set(paths) + path_times: dict[str, datetime.datetime] = {} + for line in git_log_out: + if not line: + continue + if line.startswith("time="): + current_time = safe_isotime_to_datetime(line.removeprefix("time=")) + continue + mod_type, file_paths = line.split(maxsplit=1) + assert current_time is not None + for file_path in file_paths.split("\t"): + if file_path in set_paths and file_path not in path_times: + path_times[file_path] = current_time + + # FIXME: find out why some files are not shown in "git log" + # assert set(path_times.keys()) == set_paths + if set(path_times.keys()) != set_paths: + found_times = set(path_times.keys()) + paths_without_times = set_paths.difference(found_times) + logger.warning("No times found for these paths: %s", paths_without_times) + max_time = max(time for time in path_times.values()) + for path in paths_without_times: + path_times[path] = max_time + + return path_times + + +class AndroidApiVersion: + def __init__(self, name: str, ints: tuple[int, ...]): + self.name = name + self.ints = ints + + def __repr__(self) -> str: + return f"<{self.name} ({'.'.join(str(v) for v in self.ints)})>" + + +class Releaser: + def __init__(self, release_info: dict, commit: str, revision: str, root: Path, dist_path: Path, section_printer: SectionPrinter, executer: Executer, cmake_generator: str, deps_path: Path, overwrite: bool, github: bool, fast: bool): + self.release_info = release_info + self.project = release_info["name"] + self.version = self.extract_sdl_version(root=root, release_info=release_info) + self.root = root + self.commit = commit + self.revision = revision + self.dist_path = dist_path + self.section_printer = section_printer + self.executer = executer + self.cmake_generator = cmake_generator + self.cpu_count = multiprocessing.cpu_count() + self.deps_path = deps_path + self.overwrite = overwrite + self.github = github + self.fast = fast + self.arc_time = datetime.datetime.now() + + self.artifacts: dict[str, Path] = {} + + def get_context(self, extra_context: typing.Optional[dict[str, str]]=None) -> dict[str, str]: + ctx = { + "PROJECT_NAME": self.project, + "PROJECT_VERSION": self.version, + "PROJECT_COMMIT": self.commit, + "PROJECT_REVISION": self.revision, + "PROJECT_ROOT": str(self.root), + } + if extra_context: + ctx.update(extra_context) + return ctx + + @property + def dry(self) -> bool: + return self.executer.dry + + def prepare(self): + logger.debug("Creating dist folder") + self.dist_path.mkdir(parents=True, exist_ok=True) + + @classmethod + def _path_filter(cls, path: str) -> bool: + if ".gitmodules" in path: + return True + if path.startswith(".git"): + return False + return True + + @classmethod + def _external_repo_path_filter(cls, path: str) -> bool: + if not cls._path_filter(path): + return False + if path.startswith("test/") or path.startswith("tests/"): + return False + return True + + def create_source_archives(self) -> None: + source_collector = SourceCollector(root=self.root, commit=self.commit, executer=self.executer, filter=self._path_filter) + print(f"Collecting sources of {self.project}...") + archive_tree: ArchiveFileTree = source_collector.get_archive_file_tree() + latest_mod_time = archive_tree.get_latest_mod_time() + archive_tree.add_file(NodeInArchive.from_text(arcpath=REVISION_TXT, text=f"{self.revision}\n", time=latest_mod_time)) + archive_tree.add_file(NodeInArchive.from_text(arcpath=f"{GIT_HASH_FILENAME}", text=f"{self.commit}\n", time=latest_mod_time)) + archive_tree.add_file_mapping(arc_dir="", file_mapping=self.release_info["source"].get("files", {}), file_mapping_root=self.root, context=self.get_context(), time=latest_mod_time) + + if "Makefile.am" in archive_tree: + patched_time = latest_mod_time + datetime.timedelta(minutes=1) + print(f"Makefile.am detected -> touching aclocal.m4, */Makefile.in, configure") + for node_data in archive_tree: + arc_name = os.path.basename(node_data.arcpath) + arc_name_we, arc_name_ext = os.path.splitext(arc_name) + if arc_name in ("aclocal.m4", "configure", "Makefile.in"): + print(f"Bumping time of {node_data.arcpath}") + node_data.time = patched_time + + archive_base = f"{self.project}-{self.version}" + zip_path = self.dist_path / f"{archive_base}.zip" + tgz_path = self.dist_path / f"{archive_base}.tar.gz" + txz_path = self.dist_path / f"{archive_base}.tar.xz" + + logger.info("Creating zip/tgz/txz source archives ...") + if self.dry: + zip_path.touch() + tgz_path.touch() + txz_path.touch() + else: + with Archiver(zip_path=zip_path, tgz_path=tgz_path, txz_path=txz_path) as archiver: + print(f"Adding source files of {self.project}...") + archive_tree.add_to_archiver(archive_base=archive_base, archiver=archiver) + + for extra_repo in self.release_info["source"].get("extra-repos", []): + extra_repo_root = self.root / extra_repo + assert (extra_repo_root / ".git").exists(), f"{extra_repo_root} must be a git repo" + extra_repo_commit = self.executer.check_output(["git", "rev-parse", "HEAD"], dry_out=f"gitsha-extra-repo-{extra_repo}", cwd=extra_repo_root).strip() + extra_repo_source_collector = SourceCollector(root=extra_repo_root, commit=extra_repo_commit, executer=self.executer, filter=self._external_repo_path_filter) + print(f"Collecting sources of {extra_repo} ...") + extra_repo_archive_tree = extra_repo_source_collector.get_archive_file_tree() + print(f"Adding source files of {extra_repo} ...") + extra_repo_archive_tree.add_to_archiver(archive_base=f"{archive_base}/{extra_repo}", archiver=archiver) + + for file in self.release_info["source"]["checks"]: + assert f"{archive_base}/{file}" in archiver.added_files, f"'{archive_base}/{file}' must exist" + + logger.info("... done") + + self.artifacts["src-zip"] = zip_path + self.artifacts["src-tar-gz"] = tgz_path + self.artifacts["src-tar-xz"] = txz_path + + if not self.dry: + with tgz_path.open("r+b") as f: + # Zero the embedded timestamp in the gzip'ed tarball + f.seek(4, 0) + f.write(b"\x00\x00\x00\x00") + + def create_dmg(self, configuration: str="Release") -> None: + dmg_in = self.root / self.release_info["dmg"]["path"] + xcode_project = self.root / self.release_info["dmg"]["project"] + assert xcode_project.is_dir(), f"{xcode_project} must be a directory" + assert (xcode_project / "project.pbxproj").is_file, f"{xcode_project} must contain project.pbxproj" + if not self.fast: + dmg_in.unlink(missing_ok=True) + build_xcconfig = self.release_info["dmg"].get("build-xcconfig") + if build_xcconfig: + shutil.copy(self.root / build_xcconfig, xcode_project.parent / "build.xcconfig") + + xcode_scheme = self.release_info["dmg"].get("scheme") + xcode_target = self.release_info["dmg"].get("target") + assert xcode_scheme or xcode_target, "dmg needs scheme or target" + assert not (xcode_scheme and xcode_target), "dmg cannot have both scheme and target set" + if xcode_scheme: + scheme_or_target = "-scheme" + target_like = xcode_scheme + else: + scheme_or_target = "-target" + target_like = xcode_target + self.executer.run(["xcodebuild", "ONLY_ACTIVE_ARCH=NO", "-project", xcode_project, scheme_or_target, target_like, "-configuration", configuration]) + if self.dry: + dmg_in.parent.mkdir(parents=True, exist_ok=True) + dmg_in.touch() + + assert dmg_in.is_file(), f"{self.project}.dmg was not created by xcodebuild" + + dmg_out = self.dist_path / f"{self.project}-{self.version}.dmg" + shutil.copy(dmg_in, dmg_out) + self.artifacts["dmg"] = dmg_out + + @property + def git_hash_data(self) -> bytes: + return f"{self.commit}\n".encode() + + def verify_mingw_library(self, triplet: str, path: Path): + objdump_output = self.executer.check_output([f"{triplet}-objdump", "-p", str(path)]) + libraries = re.findall(r"DLL Name: ([^\n]+)", objdump_output) + logger.info("%s (%s) libraries: %r", path, triplet, libraries) + illegal_libraries = list(filter(RE_ILLEGAL_MINGW_LIBRARIES.match, libraries)) + logger.error("Detected 'illegal' libraries: %r", illegal_libraries) + if illegal_libraries: + raise Exception(f"{path} links to illegal libraries: {illegal_libraries}") + + def create_mingw_archives(self) -> None: + build_type = "Release" + build_parent_dir = self.root / "build-mingw" + ARCH_TO_GNU_ARCH = { + # "arm64": "aarch64", + "x86": "i686", + "x64": "x86_64", + } + ARCH_TO_TRIPLET = { + # "arm64": "aarch64-w64-mingw32", + "x86": "i686-w64-mingw32", + "x64": "x86_64-w64-mingw32", + } + + new_env = dict(os.environ) + + cmake_prefix_paths = [] + mingw_deps_path = self.deps_path / "mingw-deps" + + if "dependencies" in self.release_info["mingw"]: + shutil.rmtree(mingw_deps_path, ignore_errors=True) + mingw_deps_path.mkdir() + + for triplet in ARCH_TO_TRIPLET.values(): + (mingw_deps_path / triplet).mkdir() + + def extract_filter(member: tarfile.TarInfo, path: str, /): + if member.name.startswith("SDL"): + member.name = "/".join(Path(member.name).parts[1:]) + return member + for dep in self.release_info.get("dependencies", {}): + extract_path = mingw_deps_path / f"extract-{dep}" + extract_path.mkdir() + with chdir(extract_path): + tar_path = self.deps_path / glob.glob(self.release_info["mingw"]["dependencies"][dep]["artifact"], root_dir=self.deps_path)[0] + logger.info("Extracting %s to %s", tar_path, mingw_deps_path) + assert tar_path.suffix in (".gz", ".xz") + with tarfile.open(tar_path, mode=f"r:{tar_path.suffix.strip('.')}") as tarf: + tarf.extractall(filter=extract_filter) + for arch, triplet in ARCH_TO_TRIPLET.items(): + install_cmd = self.release_info["mingw"]["dependencies"][dep]["install-command"] + extra_configure_data = { + "ARCH": ARCH_TO_GNU_ARCH[arch], + "TRIPLET": triplet, + "PREFIX": str(mingw_deps_path / triplet), + } + install_cmd = configure_text(install_cmd, context=self.get_context(extra_configure_data)) + self.executer.run(shlex.split(install_cmd), cwd=str(extract_path)) + + dep_binpath = mingw_deps_path / triplet / "bin" + assert dep_binpath.is_dir(), f"{dep_binpath} for PATH should exist" + dep_pkgconfig = mingw_deps_path / triplet / "lib/pkgconfig" + assert dep_pkgconfig.is_dir(), f"{dep_pkgconfig} for PKG_CONFIG_PATH should exist" + + new_env["PATH"] = os.pathsep.join([str(dep_binpath), new_env["PATH"]]) + new_env["PKG_CONFIG_PATH"] = str(dep_pkgconfig) + cmake_prefix_paths.append(mingw_deps_path) + + new_env["CFLAGS"] = f"-O2 -ffile-prefix-map={self.root}=/src/{self.project}" + new_env["CXXFLAGS"] = f"-O2 -ffile-prefix-map={self.root}=/src/{self.project}" + + assert any(system in self.release_info["mingw"] for system in ("autotools", "cmake")) + assert not all(system in self.release_info["mingw"] for system in ("autotools", "cmake")) + + mingw_archs = set() + arc_root = f"{self.project}-{self.version}" + archive_file_tree = ArchiveFileTree() + + if "autotools" in self.release_info["mingw"]: + for arch in self.release_info["mingw"]["autotools"]["archs"]: + triplet = ARCH_TO_TRIPLET[arch] + new_env["CC"] = f"{triplet}-gcc" + new_env["CXX"] = f"{triplet}-g++" + new_env["RC"] = f"{triplet}-windres" + + assert arch not in mingw_archs + mingw_archs.add(arch) + + build_path = build_parent_dir / f"build-{triplet}" + install_path = build_parent_dir / f"install-{triplet}" + shutil.rmtree(install_path, ignore_errors=True) + build_path.mkdir(parents=True, exist_ok=True) + context = self.get_context({ + "ARCH": arch, + "DEP_PREFIX": str(mingw_deps_path / triplet), + }) + extra_args = configure_text_list(text_list=self.release_info["mingw"]["autotools"]["args"], context=context) + + with self.section_printer.group(f"Configuring MinGW {triplet} (autotools)"): + assert "@" not in " ".join(extra_args), f"@ should not be present in extra arguments ({extra_args})" + self.executer.run([ + self.root / "configure", + f"--prefix={install_path}", + f"--includedir=${{prefix}}/include", + f"--libdir=${{prefix}}/lib", + f"--bindir=${{prefix}}/bin", + f"--host={triplet}", + f"--build=x86_64-none-linux-gnu", + "CFLAGS=-O2", + "CXXFLAGS=-O2", + "LDFLAGS=-Wl,-s", + ] + extra_args, cwd=build_path, env=new_env) + with self.section_printer.group(f"Build MinGW {triplet} (autotools)"): + self.executer.run(["make", f"-j{self.cpu_count}"], cwd=build_path, env=new_env) + with self.section_printer.group(f"Install MinGW {triplet} (autotools)"): + self.executer.run(["make", "install"], cwd=build_path, env=new_env) + self.verify_mingw_library(triplet=ARCH_TO_TRIPLET[arch], path=install_path / "bin" / f"{self.project}.dll") + archive_file_tree.add_directory_tree(arc_dir=arc_join(arc_root, triplet), path=install_path, time=self.arc_time) + + print("Recording arch-dependent extra files for MinGW development archive ...") + extra_context = { + "TRIPLET": ARCH_TO_TRIPLET[arch], + } + archive_file_tree.add_file_mapping(arc_dir=arc_root, file_mapping=self.release_info["mingw"]["autotools"].get("files", {}), file_mapping_root=self.root, context=self.get_context(extra_context=extra_context), time=self.arc_time) + + if "cmake" in self.release_info["mingw"]: + assert self.release_info["mingw"]["cmake"]["shared-static"] in ("args", "both") + for arch in self.release_info["mingw"]["cmake"]["archs"]: + triplet = ARCH_TO_TRIPLET[arch] + new_env["CC"] = f"{triplet}-gcc" + new_env["CXX"] = f"{triplet}-g++" + new_env["RC"] = f"{triplet}-windres" + + assert arch not in mingw_archs + mingw_archs.add(arch) + + context = self.get_context({ + "ARCH": arch, + "DEP_PREFIX": str(mingw_deps_path / triplet), + }) + extra_args = configure_text_list(text_list=self.release_info["mingw"]["cmake"]["args"], context=context) + + build_path = build_parent_dir / f"build-{triplet}" + install_path = build_parent_dir / f"install-{triplet}" + shutil.rmtree(install_path, ignore_errors=True) + build_path.mkdir(parents=True, exist_ok=True) + if self.release_info["mingw"]["cmake"]["shared-static"] == "args": + args_for_shared_static = ([], ) + elif self.release_info["mingw"]["cmake"]["shared-static"] == "both": + args_for_shared_static = (["-DBUILD_SHARED_LIBS=ON"], ["-DBUILD_SHARED_LIBS=OFF"]) + for arg_for_shared_static in args_for_shared_static: + with self.section_printer.group(f"Configuring MinGW {triplet} (CMake)"): + assert "@" not in " ".join(extra_args), f"@ should not be present in extra arguments ({extra_args})" + self.executer.run([ + f"cmake", + f"-S", str(self.root), "-B", str(build_path), + f"-DCMAKE_BUILD_TYPE={build_type}", + f'''-DCMAKE_C_FLAGS="-ffile-prefix-map={self.root}=/src/{self.project}"''', + f'''-DCMAKE_CXX_FLAGS="-ffile-prefix-map={self.root}=/src/{self.project}"''', + f"-DCMAKE_PREFIX_PATH={mingw_deps_path / triplet}", + f"-DCMAKE_INSTALL_PREFIX={install_path}", + f"-DCMAKE_INSTALL_INCLUDEDIR=include", + f"-DCMAKE_INSTALL_LIBDIR=lib", + f"-DCMAKE_INSTALL_BINDIR=bin", + f"-DCMAKE_INSTALL_DATAROOTDIR=share", + f"-DCMAKE_TOOLCHAIN_FILE={self.root}/build-scripts/cmake-toolchain-mingw64-{ARCH_TO_GNU_ARCH[arch]}.cmake", + f"-G{self.cmake_generator}", + ] + extra_args + ([] if self.fast else ["--fresh"]) + arg_for_shared_static, cwd=build_path, env=new_env) + with self.section_printer.group(f"Build MinGW {triplet} (CMake)"): + self.executer.run(["cmake", "--build", str(build_path), "--verbose", "--config", build_type], cwd=build_path, env=new_env) + with self.section_printer.group(f"Install MinGW {triplet} (CMake)"): + self.executer.run(["cmake", "--install", str(build_path)], cwd=build_path, env=new_env) + self.verify_mingw_library(triplet=ARCH_TO_TRIPLET[arch], path=install_path / "bin" / f"{self.project}.dll") + archive_file_tree.add_directory_tree(arc_dir=arc_join(arc_root, triplet), path=install_path, time=self.arc_time) + + print("Recording arch-dependent extra files for MinGW development archive ...") + extra_context = { + "TRIPLET": ARCH_TO_TRIPLET[arch], + } + archive_file_tree.add_file_mapping(arc_dir=arc_root, file_mapping=self.release_info["mingw"]["cmake"].get("files", {}), file_mapping_root=self.root, context=self.get_context(extra_context=extra_context), time=self.arc_time) + print("... done") + + print("Recording extra files for MinGW development archive ...") + archive_file_tree.add_file_mapping(arc_dir=arc_root, file_mapping=self.release_info["mingw"].get("files", {}), file_mapping_root=self.root, context=self.get_context(), time=self.arc_time) + print("... done") + + print("Creating zip/tgz/txz development archives ...") + zip_path = self.dist_path / f"{self.project}-devel-{self.version}-mingw.zip" + tgz_path = self.dist_path / f"{self.project}-devel-{self.version}-mingw.tar.gz" + txz_path = self.dist_path / f"{self.project}-devel-{self.version}-mingw.tar.xz" + + with Archiver(zip_path=zip_path, tgz_path=tgz_path, txz_path=txz_path) as archiver: + archive_file_tree.add_to_archiver(archive_base="", archiver=archiver) + archiver.add_git_hash(arcdir=arc_root, commit=self.commit, time=self.arc_time) + print("... done") + + self.artifacts["mingw-devel-zip"] = zip_path + self.artifacts["mingw-devel-tar-gz"] = tgz_path + self.artifacts["mingw-devel-tar-xz"] = txz_path + + def _detect_android_api(self, android_home: str) -> typing.Optional[AndroidApiVersion]: + platform_dirs = list(Path(p) for p in glob.glob(f"{android_home}/platforms/android-*")) + re_platform = re.compile("^android-([0-9]+)(?:-ext([0-9]+))?$") + platform_versions: list[AndroidApiVersion] = [] + for platform_dir in platform_dirs: + logger.debug("Found Android Platform SDK: %s", platform_dir) + if not (platform_dir / "android.jar").is_file(): + logger.debug("Skipping SDK, missing android.jar") + continue + if m:= re_platform.match(platform_dir.name): + platform_versions.append(AndroidApiVersion(name=platform_dir.name, ints=(int(m.group(1)), int(m.group(2) or 0)))) + platform_versions.sort(key=lambda v: v.ints) + logger.info("Available platform versions: %s", platform_versions) + platform_versions = list(filter(lambda v: v.ints >= self._android_api_minimum.ints, platform_versions)) + logger.info("Valid platform versions (>=%s): %s", self._android_api_minimum.ints, platform_versions) + if not platform_versions: + return None + android_api = platform_versions[0] + logger.info("Selected API version %s", android_api) + return android_api + + def _get_prefab_json_text(self) -> str: + return textwrap.dedent(f"""\ + {{ + "schema_version": 2, + "name": "{self.project}", + "version": "{self.version}", + "dependencies": [] + }} + """) + + def _get_prefab_module_json_text(self, library_name: typing.Optional[str], export_libraries: list[str]) -> str: + for lib in export_libraries: + assert isinstance(lib, str), f"{lib} must be a string" + module_json_dict = { + "export_libraries": export_libraries, + } + if library_name: + module_json_dict["library_name"] = f"lib{library_name}" + return json.dumps(module_json_dict, indent=4) + + @property + def _android_api_minimum(self) -> AndroidApiVersion: + value = self.release_info["android"]["api-minimum"] + if isinstance(value, int): + ints = (value, ) + elif isinstance(value, str): + ints = tuple(split(".")) + else: + raise ValueError("Invalid android.api-minimum: must be X or X.Y") + match len(ints): + case 1: name = f"android-{ints[0]}" + case 2: name = f"android-{ints[0]}-ext-{ints[1]}" + case _: raise ValueError("Invalid android.api-minimum: must be X or X.Y") + return AndroidApiVersion(name=name, ints=ints) + + @property + def _android_api_target(self): + return self.release_info["android"]["api-target"] + + @property + def _android_ndk_minimum(self): + return self.release_info["android"]["ndk-minimum"] + + def _get_prefab_abi_json_text(self, abi: str, cpp: bool, shared: bool) -> str: + abi_json_dict = { + "abi": abi, + "api": self._android_api_minimum.ints[0], + "ndk": self._android_ndk_minimum, + "stl": "c++_shared" if cpp else "none", + "static": not shared, + } + return json.dumps(abi_json_dict, indent=4) + + def _get_android_manifest_text(self) -> str: + return textwrap.dedent(f"""\ + + + + """) + + def create_android_archives(self, android_api: int, android_home: Path, android_ndk_home: Path) -> None: + cmake_toolchain_file = Path(android_ndk_home) / "build/cmake/android.toolchain.cmake" + if not cmake_toolchain_file.exists(): + logger.error("CMake toolchain file does not exist (%s)", cmake_toolchain_file) + raise SystemExit(1) + aar_path = self.root / "build-android" / f"{self.project}-{self.version}.aar" + android_dist_path = self.dist_path / f"{self.project}-devel-{self.version}-android.zip" + android_abis = self.release_info["android"]["abis"] + java_jars_added = False + module_data_added = False + android_deps_path = self.deps_path / "android-deps" + shutil.rmtree(android_deps_path, ignore_errors=True) + + for dep, depinfo in self.release_info["android"].get("dependencies", {}).items(): + dep_devel_zip = self.deps_path / glob.glob(depinfo["artifact"], root_dir=self.deps_path)[0] + + dep_extract_path = self.deps_path / f"extract/android/{dep}" + shutil.rmtree(dep_extract_path, ignore_errors=True) + dep_extract_path.mkdir(parents=True, exist_ok=True) + + with self.section_printer.group(f"Extracting Android dependency {dep} ({dep_devel_zip})"): + with zipfile.ZipFile(dep_devel_zip, "r") as zf: + zf.extractall(dep_extract_path) + + dep_devel_aar = dep_extract_path / glob.glob("*.aar", root_dir=dep_extract_path)[0] + self.executer.run([sys.executable, str(dep_devel_aar), "-o", str(android_deps_path)]) + + for module_name, module_info in self.release_info["android"]["modules"].items(): + assert "type" in module_info and module_info["type"] in ("interface", "library"), f"module {module_name} must have a valid type" + + aar_file_tree = ArchiveFileTree() + android_devel_file_tree = ArchiveFileTree() + + for android_abi in android_abis: + with self.section_printer.group(f"Building for Android {android_api} {android_abi}"): + build_dir = self.root / "build-android" / f"{android_abi}-build" + install_dir = self.root / "install-android" / f"{android_abi}-install" + shutil.rmtree(install_dir, ignore_errors=True) + assert not install_dir.is_dir(), f"{install_dir} should not exist prior to build" + build_type = "Release" + cmake_args = [ + "cmake", + "-S", str(self.root), + "-B", str(build_dir), + f'''-DCMAKE_C_FLAGS="-ffile-prefix-map={self.root}=/src/{self.project}"''', + f'''-DCMAKE_CXX_FLAGS="-ffile-prefix-map={self.root}=/src/{self.project}"''', + f"-DCMAKE_TOOLCHAIN_FILE={cmake_toolchain_file}", + f"-DCMAKE_PREFIX_PATH={str(android_deps_path)}", + f"-DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=BOTH", + f"-DANDROID_HOME={android_home}", + f"-DANDROID_PLATFORM={android_api}", + f"-DANDROID_ABI={android_abi}", + "-DCMAKE_POSITION_INDEPENDENT_CODE=ON", + f"-DCMAKE_INSTALL_PREFIX={install_dir}", + "-DCMAKE_INSTALL_INCLUDEDIR=include ", + "-DCMAKE_INSTALL_LIBDIR=lib", + "-DCMAKE_INSTALL_DATAROOTDIR=share", + f"-DCMAKE_BUILD_TYPE={build_type}", + f"-G{self.cmake_generator}", + ] + self.release_info["android"]["cmake"]["args"] + ([] if self.fast else ["--fresh"]) + build_args = [ + "cmake", + "--build", str(build_dir), + "--verbose", + "--config", build_type, + ] + install_args = [ + "cmake", + "--install", str(build_dir), + "--config", build_type, + ] + self.executer.run(cmake_args) + self.executer.run(build_args) + self.executer.run(install_args) + + for module_name, module_info in self.release_info["android"]["modules"].items(): + arcdir_prefab_module = f"prefab/modules/{module_name}" + if module_info["type"] == "library": + library = install_dir / module_info["library"] + assert library.suffix in (".so", ".a") + assert library.is_file(), f"CMake should have built library '{library}' for module {module_name}" + arcdir_prefab_libs = f"{arcdir_prefab_module}/libs/android.{android_abi}" + aar_file_tree.add_file(NodeInArchive.from_fs(arcpath=f"{arcdir_prefab_libs}/{library.name}", path=library, time=self.arc_time)) + aar_file_tree.add_file(NodeInArchive.from_text(arcpath=f"{arcdir_prefab_libs}/abi.json", text=self._get_prefab_abi_json_text(abi=android_abi, cpp=False, shared=library.suffix == ".so"), time=self.arc_time)) + + if not module_data_added: + library_name = None + if module_info["type"] == "library": + library_name = Path(module_info["library"]).stem.removeprefix("lib") + export_libraries = module_info.get("export-libraries", []) + aar_file_tree.add_file(NodeInArchive.from_text(arcpath=arc_join(arcdir_prefab_module, "module.json"), text=self._get_prefab_module_json_text(library_name=library_name, export_libraries=export_libraries), time=self.arc_time)) + arcdir_prefab_include = f"prefab/modules/{module_name}/include" + if "includes" in module_info: + aar_file_tree.add_file_mapping(arc_dir=arcdir_prefab_include, file_mapping=module_info["includes"], file_mapping_root=install_dir, context=self.get_context(), time=self.arc_time) + else: + aar_file_tree.add_file(NodeInArchive.from_text(arcpath=arc_join(arcdir_prefab_include, ".keep"), text="\n", time=self.arc_time)) + module_data_added = True + + if not java_jars_added: + java_jars_added = True + if "jars" in self.release_info["android"]: + classes_jar_path = install_dir / configure_text(text=self.release_info["android"]["jars"]["classes"], context=self.get_context()) + sources_jar_path = install_dir / configure_text(text=self.release_info["android"]["jars"]["sources"], context=self.get_context()) + doc_jar_path = install_dir / configure_text(text=self.release_info["android"]["jars"]["doc"], context=self.get_context()) + assert classes_jar_path.is_file(), f"CMake should have compiled the java sources and archived them into a JAR ({classes_jar_path})" + assert sources_jar_path.is_file(), f"CMake should have archived the java sources into a JAR ({sources_jar_path})" + assert doc_jar_path.is_file(), f"CMake should have archived javadoc into a JAR ({doc_jar_path})" + + aar_file_tree.add_file(NodeInArchive.from_fs(arcpath="classes.jar", path=classes_jar_path, time=self.arc_time)) + aar_file_tree.add_file(NodeInArchive.from_fs(arcpath="classes-sources.jar", path=sources_jar_path, time=self.arc_time)) + aar_file_tree.add_file(NodeInArchive.from_fs(arcpath="classes-doc.jar", path=doc_jar_path, time=self.arc_time)) + + assert ("jars" in self.release_info["android"] and java_jars_added) or "jars" not in self.release_info["android"], "Must have archived java JAR archives" + + aar_file_tree.add_file_mapping(arc_dir="", file_mapping=self.release_info["android"]["aar-files"], file_mapping_root=self.root, context=self.get_context(), time=self.arc_time) + + aar_file_tree.add_file(NodeInArchive.from_text(arcpath="prefab/prefab.json", text=self._get_prefab_json_text(), time=self.arc_time)) + aar_file_tree.add_file(NodeInArchive.from_text(arcpath="AndroidManifest.xml", text=self._get_android_manifest_text(), time=self.arc_time)) + + with Archiver(zip_path=aar_path) as archiver: + aar_file_tree.add_to_archiver(archive_base="", archiver=archiver) + archiver.add_git_hash(arcdir="", commit=self.commit, time=self.arc_time) + + android_devel_file_tree.add_file(NodeInArchive.from_fs(arcpath=aar_path.name, path=aar_path)) + android_devel_file_tree.add_file_mapping(arc_dir="", file_mapping=self.release_info["android"]["files"], file_mapping_root=self.root, context=self.get_context(), time=self.arc_time) + with Archiver(zip_path=android_dist_path) as archiver: + android_devel_file_tree.add_to_archiver(archive_base="", archiver=archiver) + archiver.add_git_hash(arcdir="", commit=self.commit, time=self.arc_time) + + self.artifacts[f"android-aar"] = android_dist_path + + def download_dependencies(self): + shutil.rmtree(self.deps_path, ignore_errors=True) + self.deps_path.mkdir(parents=True) + + if self.github: + with open(os.environ["GITHUB_OUTPUT"], "a") as f: + f.write(f"dep-path={self.deps_path.absolute()}\n") + + for dep, depinfo in self.release_info.get("dependencies", {}).items(): + startswith = depinfo["startswith"] + dep_repo = depinfo["repo"] + # FIXME: dropped "--exclude-pre-releases" + dep_string_data = self.executer.check_output(["gh", "-R", dep_repo, "release", "list", "--exclude-drafts", "--json", "name,createdAt,tagName", "--jq", f'[.[]|select(.name|startswith("{startswith}"))]|max_by(.createdAt)']).strip() + dep_data = json.loads(dep_string_data) + dep_tag = dep_data["tagName"] + dep_version = dep_data["name"] + logger.info("Download dependency %s version %s (tag=%s) ", dep, dep_version, dep_tag) + self.executer.run(["gh", "-R", dep_repo, "release", "download", dep_tag], cwd=self.deps_path) + if self.github: + with open(os.environ["GITHUB_OUTPUT"], "a") as f: + f.write(f"dep-{dep.lower()}-version={dep_version}\n") + + def verify_dependencies(self): + for dep, depinfo in self.release_info.get("dependencies", {}).items(): + if "mingw" in self.release_info: + mingw_matches = glob.glob(self.release_info["mingw"]["dependencies"][dep]["artifact"], root_dir=self.deps_path) + assert len(mingw_matches) == 1, f"Exactly one archive matches mingw {dep} dependency: {mingw_matches}" + if "dmg" in self.release_info: + dmg_matches = glob.glob(self.release_info["dmg"]["dependencies"][dep]["artifact"], root_dir=self.deps_path) + assert len(dmg_matches) == 1, f"Exactly one archive matches dmg {dep} dependency: {dmg_matches}" + if "msvc" in self.release_info: + msvc_matches = glob.glob(self.release_info["msvc"]["dependencies"][dep]["artifact"], root_dir=self.deps_path) + assert len(msvc_matches) == 1, f"Exactly one archive matches msvc {dep} dependency: {msvc_matches}" + if "android" in self.release_info: + android_matches = glob.glob(self.release_info["android"]["dependencies"][dep]["artifact"], root_dir=self.deps_path) + assert len(android_matches) == 1, f"Exactly one archive matches msvc {dep} dependency: {android_matches}" + + @staticmethod + def _arch_to_vs_platform(arch: str, configuration: str="Release") -> VsArchPlatformConfig: + ARCH_TO_VS_PLATFORM = { + "x86": VsArchPlatformConfig(arch="x86", platform="Win32", configuration=configuration), + "x64": VsArchPlatformConfig(arch="x64", platform="x64", configuration=configuration), + "arm64": VsArchPlatformConfig(arch="arm64", platform="ARM64", configuration=configuration), + } + return ARCH_TO_VS_PLATFORM[arch] + + def build_msvc(self): + with self.section_printer.group("Find Visual Studio"): + vs = VisualStudio(executer=self.executer) + for arch in self.release_info["msvc"].get("msbuild", {}).get("archs", []): + self._build_msvc_msbuild(arch_platform=self._arch_to_vs_platform(arch=arch), vs=vs) + if "cmake" in self.release_info["msvc"]: + deps_path = self.root / "msvc-deps" + shutil.rmtree(deps_path, ignore_errors=True) + dep_roots = [] + for dep, depinfo in self.release_info["msvc"].get("dependencies", {}).items(): + dep_extract_path = deps_path / f"extract-{dep}" + msvc_zip = self.deps_path / glob.glob(depinfo["artifact"], root_dir=self.deps_path)[0] + with zipfile.ZipFile(msvc_zip, "r") as zf: + zf.extractall(dep_extract_path) + contents_msvc_zip = glob.glob(str(dep_extract_path / "*")) + assert len(contents_msvc_zip) == 1, f"There must be exactly one root item in the root directory of {dep}" + dep_roots.append(contents_msvc_zip[0]) + + for arch in self.release_info["msvc"].get("cmake", {}).get("archs", []): + self._build_msvc_cmake(arch_platform=self._arch_to_vs_platform(arch=arch), dep_roots=dep_roots) + with self.section_printer.group("Create SDL VC development zip"): + self._build_msvc_devel() + + def _build_msvc_msbuild(self, arch_platform: VsArchPlatformConfig, vs: VisualStudio): + platform_context = self.get_context(arch_platform.extra_context()) + for dep, depinfo in self.release_info["msvc"].get("dependencies", {}).items(): + msvc_zip = self.deps_path / glob.glob(depinfo["artifact"], root_dir=self.deps_path)[0] + + src_globs = [configure_text(instr["src"], context=platform_context) for instr in depinfo["copy"]] + with zipfile.ZipFile(msvc_zip, "r") as zf: + for member in zf.namelist(): + member_path = "/".join(Path(member).parts[1:]) + for src_i, src_glob in enumerate(src_globs): + if fnmatch.fnmatch(member_path, src_glob): + dst = (self.root / configure_text(depinfo["copy"][src_i]["dst"], context=platform_context)).resolve() / Path(member_path).name + zip_data = zf.read(member) + if dst.exists(): + identical = False + if dst.is_file(): + orig_bytes = dst.read_bytes() + if orig_bytes == zip_data: + identical = True + if not identical: + logger.warning("Extracting dependency %s, will cause %s to be overwritten", dep, dst) + if not self.overwrite: + raise RuntimeError("Run with --overwrite to allow overwriting") + logger.debug("Extracting %s -> %s", member, dst) + + dst.parent.mkdir(exist_ok=True, parents=True) + dst.write_bytes(zip_data) + + prebuilt_paths = set(self.root / full_prebuilt_path for prebuilt_path in self.release_info["msvc"]["msbuild"].get("prebuilt", []) for full_prebuilt_path in glob.glob(configure_text(prebuilt_path, context=platform_context), root_dir=self.root)) + msbuild_paths = set(self.root / configure_text(f, context=platform_context) for file_mapping in (self.release_info["msvc"]["msbuild"]["files-lib"], self.release_info["msvc"]["msbuild"]["files-devel"]) for files_list in file_mapping.values() for f in files_list) + assert prebuilt_paths.issubset(msbuild_paths), f"msvc.msbuild.prebuilt must be a subset of (msvc.msbuild.files-lib, msvc.msbuild.files-devel)" + built_paths = msbuild_paths.difference(prebuilt_paths) + logger.info("MSbuild builds these files, to be included in the package: %s", built_paths) + if not self.fast: + for b in built_paths: + b.unlink(missing_ok=True) + + rel_projects: list[str] = self.release_info["msvc"]["msbuild"]["projects"] + projects = list(self.root / p for p in rel_projects) + + directory_build_props_src_relpath = self.release_info["msvc"]["msbuild"].get("directory-build-props") + for project in projects: + dir_b_props = project.parent / "Directory.Build.props" + dir_b_props.unlink(missing_ok = True) + if directory_build_props_src_relpath: + src = self.root / directory_build_props_src_relpath + logger.debug("Copying %s -> %s", src, dir_b_props) + shutil.copy(src=src, dst=dir_b_props) + + with self.section_printer.group(f"Build {arch_platform.arch} VS binary"): + vs.build(arch_platform=arch_platform, projects=projects) + + if self.dry: + for b in built_paths: + b.parent.mkdir(parents=True, exist_ok=True) + b.touch() + + for b in built_paths: + assert b.is_file(), f"{b} has not been created" + b.parent.mkdir(parents=True, exist_ok=True) + b.touch() + + zip_path = self.dist_path / f"{self.project}-{self.version}-win32-{arch_platform.arch}.zip" + zip_path.unlink(missing_ok=True) + + logger.info("Collecting files...") + archive_file_tree = ArchiveFileTree() + archive_file_tree.add_file_mapping(arc_dir="", file_mapping=self.release_info["msvc"]["msbuild"]["files-lib"], file_mapping_root=self.root, context=platform_context, time=self.arc_time) + archive_file_tree.add_file_mapping(arc_dir="", file_mapping=self.release_info["msvc"]["files-lib"], file_mapping_root=self.root, context=platform_context, time=self.arc_time) + + logger.info("Writing to %s", zip_path) + with Archiver(zip_path=zip_path) as archiver: + arc_root = f"" + archive_file_tree.add_to_archiver(archive_base=arc_root, archiver=archiver) + archiver.add_git_hash(arcdir=arc_root, commit=self.commit, time=self.arc_time) + self.artifacts[f"VC-{arch_platform.arch}"] = zip_path + + for p in built_paths: + assert p.is_file(), f"{p} should exist" + + def _arch_platform_to_build_path(self, arch_platform: VsArchPlatformConfig) -> Path: + return self.root / f"build-vs-{arch_platform.arch}" + + def _arch_platform_to_install_path(self, arch_platform: VsArchPlatformConfig) -> Path: + return self._arch_platform_to_build_path(arch_platform) / "prefix" + + def _build_msvc_cmake(self, arch_platform: VsArchPlatformConfig, dep_roots: list[Path]): + build_path = self._arch_platform_to_build_path(arch_platform) + install_path = self._arch_platform_to_install_path(arch_platform) + platform_context = self.get_context(extra_context=arch_platform.extra_context()) + + build_type = "Release" + extra_context = { + "ARCH": arch_platform.arch, + "PLATFORM": arch_platform.platform, + } + + built_paths = set(install_path / configure_text(f, context=platform_context) for file_mapping in (self.release_info["msvc"]["cmake"]["files-lib"], self.release_info["msvc"]["cmake"]["files-devel"]) for files_list in file_mapping.values() for f in files_list) + logger.info("CMake builds these files, to be included in the package: %s", built_paths) + if not self.fast: + for b in built_paths: + b.unlink(missing_ok=True) + + shutil.rmtree(install_path, ignore_errors=True) + build_path.mkdir(parents=True, exist_ok=True) + with self.section_printer.group(f"Configure VC CMake project for {arch_platform.arch}"): + self.executer.run([ + "cmake", "-S", str(self.root), "-B", str(build_path), + "-A", arch_platform.platform, + "-DCMAKE_INSTALL_BINDIR=bin", + "-DCMAKE_INSTALL_DATAROOTDIR=share", + "-DCMAKE_INSTALL_INCLUDEDIR=include", + "-DCMAKE_INSTALL_LIBDIR=lib", + f"-DCMAKE_BUILD_TYPE={build_type}", + f"-DCMAKE_INSTALL_PREFIX={install_path}", + # MSVC debug information format flags are selected by an abstraction + "-DCMAKE_POLICY_DEFAULT_CMP0141=NEW", + # MSVC debug information format + "-DCMAKE_MSVC_DEBUG_INFORMATION_FORMAT=ProgramDatabase", + # Linker flags for executables + "-DCMAKE_EXE_LINKER_FLAGS=-INCREMENTAL:NO -DEBUG -OPT:REF -OPT:ICF", + # Linker flag for shared libraries + "-DCMAKE_SHARED_LINKER_FLAGS=-INCREMENTAL:NO -DEBUG -OPT:REF -OPT:ICF", + # MSVC runtime library flags are selected by an abstraction + "-DCMAKE_POLICY_DEFAULT_CMP0091=NEW", + # Use statically linked runtime (-MT) (ideally, should be "MultiThreaded$<$:Debug>") + "-DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded", + f"-DCMAKE_PREFIX_PATH={';'.join(str(s) for s in dep_roots)}", + ] + self.release_info["msvc"]["cmake"]["args"] + ([] if self.fast else ["--fresh"])) + + with self.section_printer.group(f"Build VC CMake project for {arch_platform.arch}"): + self.executer.run(["cmake", "--build", str(build_path), "--verbose", "--config", build_type]) + with self.section_printer.group(f"Install VC CMake project for {arch_platform.arch}"): + self.executer.run(["cmake", "--install", str(build_path), "--config", build_type]) + + if self.dry: + for b in built_paths: + b.parent.mkdir(parents=True, exist_ok=True) + b.touch() + + zip_path = self.dist_path / f"{self.project}-{self.version}-win32-{arch_platform.arch}.zip" + zip_path.unlink(missing_ok=True) + + logger.info("Collecting files...") + archive_file_tree = ArchiveFileTree() + archive_file_tree.add_file_mapping(arc_dir="", file_mapping=self.release_info["msvc"]["cmake"]["files-lib"], file_mapping_root=install_path, context=platform_context, time=self.arc_time) + archive_file_tree.add_file_mapping(arc_dir="", file_mapping=self.release_info["msvc"]["files-lib"], file_mapping_root=self.root, context=self.get_context(extra_context=extra_context), time=self.arc_time) + + logger.info("Creating %s", zip_path) + with Archiver(zip_path=zip_path) as archiver: + arc_root = f"" + archive_file_tree.add_to_archiver(archive_base=arc_root, archiver=archiver) + archiver.add_git_hash(arcdir=arc_root, commit=self.commit, time=self.arc_time) + + for p in built_paths: + assert p.is_file(), f"{p} should exist" + + def _build_msvc_devel(self) -> None: + zip_path = self.dist_path / f"{self.project}-devel-{self.version}-VC.zip" + arc_root = f"{self.project}-{self.version}" + + def copy_files_devel(ctx): + archive_file_tree.add_file_mapping(arc_dir=arc_root, file_mapping=self.release_info["msvc"]["files-devel"], file_mapping_root=self.root, context=ctx, time=self.arc_time) + + + logger.info("Collecting files...") + archive_file_tree = ArchiveFileTree() + if "msbuild" in self.release_info["msvc"]: + for arch in self.release_info["msvc"]["msbuild"]["archs"]: + arch_platform = self._arch_to_vs_platform(arch=arch) + platform_context = self.get_context(arch_platform.extra_context()) + archive_file_tree.add_file_mapping(arc_dir=arc_root, file_mapping=self.release_info["msvc"]["msbuild"]["files-devel"], file_mapping_root=self.root, context=platform_context, time=self.arc_time) + copy_files_devel(ctx=platform_context) + if "cmake" in self.release_info["msvc"]: + for arch in self.release_info["msvc"]["cmake"]["archs"]: + arch_platform = self._arch_to_vs_platform(arch=arch) + platform_context = self.get_context(arch_platform.extra_context()) + archive_file_tree.add_file_mapping(arc_dir=arc_root, file_mapping=self.release_info["msvc"]["cmake"]["files-devel"], file_mapping_root=self._arch_platform_to_install_path(arch_platform), context=platform_context, time=self.arc_time) + copy_files_devel(ctx=platform_context) + + with Archiver(zip_path=zip_path) as archiver: + archive_file_tree.add_to_archiver(archive_base="", archiver=archiver) + archiver.add_git_hash(arcdir=arc_root, commit=self.commit, time=self.arc_time) + self.artifacts["VC-devel"] = zip_path + + @classmethod + def extract_sdl_version(cls, root: Path, release_info: dict) -> str: + with open(root / release_info["version"]["file"], "r") as f: + text = f.read() + major = next(re.finditer(release_info["version"]["re_major"], text, flags=re.M)).group(1) + minor = next(re.finditer(release_info["version"]["re_minor"], text, flags=re.M)).group(1) + micro = next(re.finditer(release_info["version"]["re_micro"], text, flags=re.M)).group(1) + return f"{major}.{minor}.{micro}" + + +def main(argv=None) -> int: + if sys.version_info < (3, 11): + logger.error("This script needs at least python 3.11") + return 1 + + parser = argparse.ArgumentParser(allow_abbrev=False, description="Create SDL release artifacts") + parser.add_argument("--root", metavar="DIR", type=Path, default=Path(__file__).absolute().parents[1], help="Root of project") + parser.add_argument("--release-info", metavar="JSON", dest="path_release_info", type=Path, default=Path(__file__).absolute().parent / "release-info.json", help="Path of release-info.json") + parser.add_argument("--dependency-folder", metavar="FOLDER", dest="deps_path", type=Path, default="deps", help="Directory containing pre-built archives of dependencies (will be removed when downloading archives)") + parser.add_argument("--out", "-o", metavar="DIR", dest="dist_path", type=Path, default="dist", help="Output directory") + parser.add_argument("--github", action="store_true", help="Script is running on a GitHub runner") + parser.add_argument("--commit", default="HEAD", help="Git commit/tag of which a release should be created") + parser.add_argument("--actions", choices=["download", "source", "android", "mingw", "msvc", "dmg"], required=True, nargs="+", dest="actions", help="What to do?") + parser.set_defaults(loglevel=logging.INFO) + parser.add_argument('--vs-year', dest="vs_year", help="Visual Studio year") + parser.add_argument('--android-api', dest="android_api", help="Android API version") + parser.add_argument('--android-home', dest="android_home", default=os.environ.get("ANDROID_HOME"), help="Android Home folder") + parser.add_argument('--android-ndk-home', dest="android_ndk_home", default=os.environ.get("ANDROID_NDK_HOME"), help="Android NDK Home folder") + parser.add_argument('--cmake-generator', dest="cmake_generator", default="Ninja", help="CMake Generator") + parser.add_argument('--debug', action='store_const', const=logging.DEBUG, dest="loglevel", help="Print script debug information") + parser.add_argument('--dry-run', action='store_true', dest="dry", help="Don't execute anything") + parser.add_argument('--force', action='store_true', dest="force", help="Ignore a non-clean git tree") + parser.add_argument('--overwrite', action='store_true', dest="overwrite", help="Allow potentially overwriting other projects") + parser.add_argument('--fast', action='store_true', dest="fast", help="Don't do a rebuild") + + args = parser.parse_args(argv) + logging.basicConfig(level=args.loglevel, format='[%(levelname)s] %(message)s') + args.deps_path = args.deps_path.absolute() + args.dist_path = args.dist_path.absolute() + args.root = args.root.absolute() + args.dist_path = args.dist_path.absolute() + if args.dry: + args.dist_path = args.dist_path / "dry" + + if args.github: + section_printer: SectionPrinter = GitHubSectionPrinter() + else: + section_printer = SectionPrinter() + + if args.github and "GITHUB_OUTPUT" not in os.environ: + os.environ["GITHUB_OUTPUT"] = "/tmp/github_output.txt" + + executer = Executer(root=args.root, dry=args.dry) + + root_git_hash_path = args.root / GIT_HASH_FILENAME + root_is_maybe_archive = root_git_hash_path.is_file() + if root_is_maybe_archive: + logger.warning("%s detected: Building from archive", GIT_HASH_FILENAME) + archive_commit = root_git_hash_path.read_text().strip() + if args.commit != archive_commit: + logger.warning("Commit argument is %s, but archive commit is %s. Using %s.", args.commit, archive_commit, archive_commit) + args.commit = archive_commit + revision = (args.root / REVISION_TXT).read_text().strip() + else: + args.commit = executer.check_output(["git", "rev-parse", args.commit], dry_out="e5812a9fd2cda317b503325a702ba3c1c37861d9").strip() + revision = executer.check_output(["git", "describe", "--always", "--tags", "--long", args.commit], dry_out="preview-3.1.3-96-g9512f2144").strip() + logger.info("Using commit %s", args.commit) + + try: + with args.path_release_info.open() as f: + release_info = json.load(f) + except FileNotFoundError: + logger.error(f"Could not find {args.path_release_info}") + + releaser = Releaser( + release_info=release_info, + commit=args.commit, + revision=revision, + root=args.root, + dist_path=args.dist_path, + executer=executer, + section_printer=section_printer, + cmake_generator=args.cmake_generator, + deps_path=args.deps_path, + overwrite=args.overwrite, + github=args.github, + fast=args.fast, + ) + + if root_is_maybe_archive: + logger.warning("Building from archive. Skipping clean git tree check.") + else: + porcelain_status = executer.check_output(["git", "status", "--ignored", "--porcelain"], dry_out="\n").strip() + if porcelain_status: + print(porcelain_status) + logger.warning("The tree is dirty! Do not publish any generated artifacts!") + if not args.force: + raise Exception("The git repo contains modified and/or non-committed files. Run with --force to ignore.") + + if args.fast: + logger.warning("Doing fast build! Do not publish generated artifacts!") + + with section_printer.group("Arguments"): + print(f"project = {releaser.project}") + print(f"version = {releaser.version}") + print(f"revision = {revision}") + print(f"commit = {args.commit}") + print(f"out = {args.dist_path}") + print(f"actions = {args.actions}") + print(f"dry = {args.dry}") + print(f"force = {args.force}") + print(f"overwrite = {args.overwrite}") + print(f"cmake_generator = {args.cmake_generator}") + + releaser.prepare() + + if "download" in args.actions: + releaser.download_dependencies() + + if set(args.actions).intersection({"msvc", "mingw", "android"}): + print("Verifying presence of dependencies (run 'download' action to download) ...") + releaser.verify_dependencies() + print("... done") + + if "source" in args.actions: + if root_is_maybe_archive: + raise Exception("Cannot build source archive from source archive") + with section_printer.group("Create source archives"): + releaser.create_source_archives() + + if "dmg" in args.actions: + if platform.system() != "Darwin" and not args.dry: + parser.error("framework artifact(s) can only be built on Darwin") + + releaser.create_dmg() + + if "msvc" in args.actions: + if platform.system() != "Windows" and not args.dry: + parser.error("msvc artifact(s) can only be built on Windows") + releaser.build_msvc() + + if "mingw" in args.actions: + releaser.create_mingw_archives() + + if "android" in args.actions: + if args.android_home is None or not Path(args.android_home).is_dir(): + parser.error("Invalid $ANDROID_HOME or --android-home: must be a directory containing the Android SDK") + if args.android_ndk_home is None or not Path(args.android_ndk_home).is_dir(): + parser.error("Invalid $ANDROID_NDK_HOME or --android_ndk_home: must be a directory containing the Android NDK") + if args.android_api is None: + with section_printer.group("Detect Android APIS"): + args.android_api = releaser._detect_android_api(android_home=args.android_home) + else: + try: + android_api_ints = tuple(int(v) for v in args.android_api.split(".")) + match len(android_api_ints): + case 1: android_api_name = f"android-{android_api_ints[0]}" + case 2: android_api_name = f"android-{android_api_ints[0]}-ext-{android_api_ints[1]}" + case _: raise ValueError + except ValueError: + logger.error("Invalid --android-api, must be a 'X' or 'X.Y' version") + args.android_api = AndroidApiVersion(ints=android_api_ints, name=android_api_name) + if args.android_api is None: + parser.error("Invalid --android-api, and/or could not be detected") + android_api_path = Path(args.android_home) / f"platforms/{args.android_api.name}" + if not android_api_path.is_dir(): + parser.error(f"Android API directory does not exist ({android_api_path})") + with section_printer.group("Android arguments"): + print(f"android_home = {args.android_home}") + print(f"android_ndk_home = {args.android_ndk_home}") + print(f"android_api = {args.android_api}") + releaser.create_android_archives( + android_api=args.android_api.ints[0], + android_home=args.android_home, + android_ndk_home=args.android_ndk_home, + ) + with section_printer.group("Summary"): + print(f"artifacts = {releaser.artifacts}") + + if args.github: + with open(os.environ["GITHUB_OUTPUT"], "a") as f: + f.write(f"project={releaser.project}\n") + f.write(f"version={releaser.version}\n") + for k, v in releaser.artifacts.items(): + f.write(f"{k}={v.name}\n") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/build-scripts/create-release.py b/build-scripts/create-release.py new file mode 100755 index 000000000..14916fa8b --- /dev/null +++ b/build-scripts/create-release.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python3 + +import argparse +from pathlib import Path +import json +import logging +import re +import subprocess + +ROOT = Path(__file__).resolve().parents[1] + + +def determine_remote() -> str: + text = (ROOT / "build-scripts/release-info.json").read_text() + release_info = json.loads(text) + if "remote" in release_info: + return release_info["remote"] + project_with_version = release_info["name"] + project, _ = re.subn("([^a-zA-Z_])", "", project_with_version) + return f"libsdl-org/{project}" + + +def main(): + default_remote = determine_remote() + + parser = argparse.ArgumentParser(allow_abbrev=False) + parser.add_argument("--ref", required=True, help=f"Name of branch or tag containing release.yml") + parser.add_argument("--remote", "-R", default=default_remote, help=f"Remote repo (default={default_remote})") + parser.add_argument("--commit", help=f"Input 'commit' of release.yml (default is the hash of the ref)") + args = parser.parse_args() + + if args.commit is None: + args.commit = subprocess.check_output(["git", "rev-parse", args.ref], cwd=ROOT, text=True).strip() + + + print(f"Running release.yml workflow:") + print(f" remote = {args.remote}") + print(f" ref = {args.ref}") + print(f" commit = {args.commit}") + + subprocess.check_call(["gh", "-R", args.remote, "workflow", "run", "release.yml", "--ref", args.ref, "-f", f"commit={args.commit}"], cwd=ROOT) + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/build-scripts/pkg-support/msvc/INSTALL.md b/build-scripts/pkg-support/msvc/INSTALL.md new file mode 100644 index 000000000..1d9d32c31 --- /dev/null +++ b/build-scripts/pkg-support/msvc/INSTALL.md @@ -0,0 +1,11 @@ + +# Using this package + +This package contains sdl12-compat built for Visual Studio. + +To use this package, edit your project properties: +- Add the include directory to "VC++ Directories" -> "Include Directories" +- Add the lib/_arch_ directory to "VC++ Directories" -> "Library Directories" +- Add SDL.lib and SDLmain.lib to Linker -> Input -> "Additional Dependencies" +- Copy lib/_arch_/SDL.dll, lib/_arch_/SDL2.dll, and lib/_arch_/SDL3.dll to your project directory. + diff --git a/build-scripts/pkg-support/msvc/README.md b/build-scripts/pkg-support/msvc/README.md new file mode 100644 index 000000000..2a7a2b147 --- /dev/null +++ b/build-scripts/pkg-support/msvc/README.md @@ -0,0 +1,21 @@ + +Simple DirectMedia Layer (SDL for short) is a cross-platform library +designed to make it easy to write multi-media software, such as games +and emulators. + +You can find the latest release and additional information at: +https://www.libsdl.org/ + +This code is a compatibility layer; it provides a binary and source +compatible API for programs written against SDL 1.2, but it uses SDL 2.0 +behind the scenes. If you are writing new code, please target SDL 3.0 +directly and do not use this layer. + +Installation instructions are available in [INSTALL.md](INSTALL.md). + +This library is distributed under the terms of the zlib license, +available in [LICENSE.txt](LICENSE.txt). + +Enjoy! + +Sam Lantinga (slouken@libsdl.org) diff --git a/build-scripts/pkg-support/msvc/x64/INSTALL.md.in b/build-scripts/pkg-support/msvc/x64/INSTALL.md.in new file mode 100644 index 000000000..48e1f5cc2 --- /dev/null +++ b/build-scripts/pkg-support/msvc/x64/INSTALL.md.in @@ -0,0 +1,7 @@ + +# Using this package + +This package contains @<@PROJECT_NAME@>@ built for x64 Windows. + +To use this package, simply replace an existing 64-bit SDL.dll with the ones included here. + diff --git a/build-scripts/pkg-support/msvc/x86/INSTALL.md.in b/build-scripts/pkg-support/msvc/x86/INSTALL.md.in new file mode 100644 index 000000000..89f00fd76 --- /dev/null +++ b/build-scripts/pkg-support/msvc/x86/INSTALL.md.in @@ -0,0 +1,7 @@ + +# Using this package + +This package contains @<@PROJECT_NAME@>@ built for x86 Windows. + +To use this package, simply replace an existing 32-bit SDL.dll with the ones included here. + diff --git a/build-scripts/release-info.json b/build-scripts/release-info.json new file mode 100644 index 000000000..33f531ac8 --- /dev/null +++ b/build-scripts/release-info.json @@ -0,0 +1,87 @@ +{ + "name": "sdl12-compat", + "remote": "libsdl-org/sdl12-compat", + "dependencies": { + "SDL2": { + "startswith": "2.", + "repo": "libsdl-org/SDL" + }, + "SDL3": { + "startswith": "3.", + "repo": "libsdl-org/SDL" + } + }, + "version": { + "file": "include/SDL/SDL_version.h", + "re_major": "^#define SDL_MAJOR_VERSION\\s+([0-9]+)$", + "re_minor": "^#define SDL_MINOR_VERSION\\s+([0-9]+)$", + "re_micro": "^#define SDL_PATCHLEVEL\\s+([0-9]+)$" + }, + "source": { + "checks": [ + "src/SDL12_compat.c", + "include/SDL/SDL_pixels.h", + "test/testsprite.c" + ] + }, + "msvc": { + "cmake": { + "archs": [ + "x86", + "x64" + ], + "args": [ + "-DSDL12COMPAT_VENDOR_INFO=libsdl.org", + "-DSDL12COMPAT_INSTALL_SDL2=ON", + "-DSDL12COMPAT_INSTALL_SDL3=ON", + "-DSDL12TESTS=OFF", + "-DSDL12DEVEL=ON", + "-DSTATICDEVEL=OFF" + ], + "files-lib": { + "": [ + "bin/SDL.dll", + "bin/SDL2.dll", + "bin/SDL3.dll" + ] + }, + "files-devel": { + "lib/@<@ARCH@>@": [ + "bin/SDL.dll", + "bin/SDL2.dll", + "bin/SDL3.dll", + "bin/SDL.pdb", + "bin/SDL2.pdb", + "bin/SDL3.pdb", + "lib/SDL.lib", + "lib/SDLmain.lib" + ] + } + }, + "files-lib": { + "": [ + "build-scripts/pkg-support/msvc/@<@ARCH@>@/INSTALL.md.in:INSTALL.md", + "LICENSE.txt", + "build-scripts/pkg-support/msvc/README.md" + ] + }, + "files-devel": { + "": [ + "build-scripts/pkg-support/msvc/INSTALL.md", + "LICENSE.txt", + "build-scripts/pkg-support/msvc/README.md" + ], + "include": [ + "include/SDL/*" + ] + }, + "dependencies": { + "SDL2": { + "artifact": "SDL2-devel-*-VC.zip" + }, + "SDL3": { + "artifact": "SDL3-devel-*-VC.zip" + } + } + } +} diff --git a/build-scripts/test-versioning.sh b/build-scripts/test-versioning.sh new file mode 100755 index 000000000..305c89a4d --- /dev/null +++ b/build-scripts/test-versioning.sh @@ -0,0 +1,101 @@ +#!/bin/sh +# Copyright 2022 Collabora Ltd. +# SPDX-License-Identifier: Zlib + +set -eu + +cd `dirname $0`/.. + +ref_major=$(sed -ne 's/^#define SDL_MAJOR_VERSION *//p' include/SDL/SDL_version.h) +ref_minor=$(sed -ne 's/^#define SDL_MINOR_VERSION *//p' include/SDL/SDL_version.h) +ref_micro=$(sed -ne 's/^#define SDL_PATCHLEVEL *//p' include/SDL/SDL_version.h) +ref_version="${ref_major}.${ref_minor}.${ref_micro}" + +tests=0 +failed=0 + +ok () { + tests=$(( tests + 1 )) + echo "ok - $*" +} + +not_ok () { + tests=$(( tests + 1 )) + echo "not ok - $*" + failed=1 +} + +version=$(sed -Ene 's/^project\(sdl[0-9]+_compat VERSION ([0-9.]*) LANGUAGES C\)$/\1/p' CMakeLists.txt) + +if [ "$ref_version" = "$version" ]; then + ok "CMakeLists.txt $version" +else + not_ok "CMakeLists.txt $version disagrees with SDL_version.h $ref_version" +fi + +tuple=$(sed -ne 's/^ *FILEVERSION *//p' src/version.rc | tr -d '\r') +ref_tuple="${ref_major},${ref_minor},${ref_micro},0" + +if [ "$ref_tuple" = "$tuple" ]; then + ok "version.rc FILEVERSION $tuple" +else + not_ok "version.rc FILEVERSION $tuple disagrees with SDL_version.h $ref_tuple" +fi + +tuple=$(sed -ne 's/^ *PRODUCTVERSION *//p' src/version.rc | tr -d '\r') + +if [ "$ref_tuple" = "$tuple" ]; then + ok "version.rc PRODUCTVERSION $tuple" +else + not_ok "version.rc PRODUCTVERSION $tuple disagrees with SDL_version.h $ref_tuple" +fi + +tuple=$(sed -Ene 's/^ *VALUE "FileVersion", "([0-9, ]*)\\0"\r?$/\1/p' src/version.rc | tr -d '\r') +ref_tuple="${ref_major}, ${ref_minor}, ${ref_micro}, 0" + +if [ "$ref_tuple" = "$tuple" ]; then + ok "version.rc FileVersion $tuple" +else + not_ok "version.rc FileVersion $tuple disagrees with SDL_version.h $ref_tuple" +fi + +tuple=$(sed -Ene 's/^ *VALUE "ProductVersion", "([0-9, ]*)\\0"\r?$/\1/p' src/version.rc | tr -d '\r') + +if [ "$ref_tuple" = "$tuple" ]; then + ok "version.rc ProductVersion $tuple" +else + not_ok "version.rc ProductVersion $tuple disagrees with SDL_version.h $ref_tuple" +fi + +micro=$(sed -Ene 's/^#define SDL12_COMPAT_VERSION ([0-9]+)$/\1/p' src/SDL12_compat.c) + +if [ "$ref_micro" = "$micro" ]; then + ok "SDL12_compat.c SDL12_COMPAT_VERSION $micro" +else + not_ok "SDL12_compat.c SDL12_COMPAT_VERSION $micro disagrees with SDL_version.h $ref_micro" +fi + +so_version="1.2.$ref_micro" +compat_version="1.0" +dylib_version="12.$ref_micro" + +ref_dylib_versions="$compat_version $dylib_version" +dylib_versions=$(sed -Ene 's/^LDFLAGS\+= -Wl,-compatibility_version,([0-9.]+) -Wl,-current_version,([0-9.]+)$/\1 \2/p' src/Makefile.darwin) + +if [ "$ref_dylib_versions" = "$dylib_versions" ]; then + ok "Makefile.darwin LDFLAGS $dylib_versions" +else + not_ok "Makefile.darwin LDFLAGS $dylib_versions disagrees with reference $ref_dylib_versions" +fi + +ref_so_version="$so_version" +so_version=$(sed -Ene 's/^SHLIB = libSDL-1.2.so.([0-9.]+)$/\1/p' src/Makefile.linux) + +if [ "$ref_so_version" = "$so_version" ]; then + ok "Makefile.linux SHLIB $so_version" +else + not_ok "Makefile.linux SHLIB $so_version disagrees with reference $ref_so_version" +fi + +echo "1..$tests" +exit "$failed" diff --git a/update_version.sh b/build-scripts/update-version.sh similarity index 98% rename from update_version.sh rename to build-scripts/update-version.sh index 840c7b556..26936522a 100755 --- a/update_version.sh +++ b/build-scripts/update-version.sh @@ -1,5 +1,7 @@ #!/bin/sh +cd `dirname $0`/.. + if [ -z $1 ]; then echo "USAGE: $0 " 1>&2 exit 1 From 456fae201cace6fff1ea6dd39e031b49186caf33 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Mon, 27 Oct 2025 09:08:45 -0700 Subject: [PATCH 560/606] Fixed build warnings --- src/SDL12_compat.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 2654927ac..e122fd9a0 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -5071,10 +5071,10 @@ EventFilter20to12(void *data, SDL_Event *event20) case SDLK12_UNKNOWN: FlushPendingKeydownEvent(0); break; - case SDLK_SPACE: + case SDLK12_SPACE: FlushPendingKeydownEvent(' '); break; - case SDLK_DELETE: + case SDLK12_DELETE: FlushPendingKeydownEvent('\x7F'); break; default: @@ -7734,7 +7734,7 @@ DECLSPEC12 SDL12_GrabMode SDLCALL SDL_WM_GrabInput(SDL12_GrabMode mode) { if (mode != SDL12_GRAB_QUERY) { - VideoWindowGrabWanted = mode; + VideoWindowGrabWanted = (mode == SDL12_GRAB_ON) ? SDL_TRUE : SDL_FALSE; UpdateInputGrab(); } return VideoWindowGrabWanted ? SDL12_GRAB_ON : SDL12_GRAB_OFF; From 6595f6e405844cbca4a55e47eaa29ccec0cdd75f Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Mon, 27 Oct 2025 09:10:11 -0700 Subject: [PATCH 561/606] Don't include glu.h by default This isn't available by default in modern Linux SDKs, and probably not used by anyone building SDL 1.2 applications. If an SDL 1.2 app is using glu.h, it can define SDL_INCLUDE_GLU_H to have it included. Fixes https://github.com/libsdl-org/sdl12-compat/issues/358 --- include/SDL/SDL_opengl.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/SDL/SDL_opengl.h b/include/SDL/SDL_opengl.h index 776541a20..ba92b114f 100644 --- a/include/SDL/SDL_opengl.h +++ b/include/SDL/SDL_opengl.h @@ -45,11 +45,15 @@ real SDL-1.2 available to you. */ #endif #if defined(__MACOSX__) #include /* Header File For The OpenGL Library */ +#ifdef SDL_INCLUDE_GLU_H #include /* Header File For The GLU Library */ +#endif #else #include /* Header File For The OpenGL Library */ +#ifdef SDL_INCLUDE_GLU_H #include /* Header File For The GLU Library */ #endif +#endif #ifndef NO_SDL_GLEXT #undef __glext_h_ #undef __gl_glext_h_ From ca4b3f7d077128a6a7596c76931155a7a9ccf524 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Mon, 27 Oct 2025 09:30:43 -0700 Subject: [PATCH 562/606] Updated release workflow (#375) Co-authored-by: Anonymous Maarten --- .github/actions/setup-ninja/action.yml | 62 +++++++++++++++ .github/workflows/release.yml | 83 +++++--------------- CMakeLists.txt | 104 +++++-------------------- build-scripts/build-release.py | 20 +++-- build-scripts/release-info.json | 44 ++++++----- test/CMakeLists.txt | 98 +++++++++++++++++++++++ 6 files changed, 237 insertions(+), 174 deletions(-) create mode 100644 .github/actions/setup-ninja/action.yml create mode 100644 test/CMakeLists.txt diff --git a/.github/actions/setup-ninja/action.yml b/.github/actions/setup-ninja/action.yml new file mode 100644 index 000000000..a1d3ad983 --- /dev/null +++ b/.github/actions/setup-ninja/action.yml @@ -0,0 +1,62 @@ +name: 'Setup ninja' +description: 'Download ninja and add it to the PATH environment variable' +inputs: + version: + description: 'Ninja version' + default: '1.12.1' +runs: + using: 'composite' + steps: + - name: 'Calculate variables' + id: calc + shell: sh + run: | + case "${{ runner.os }}-${{ runner.arch }}" in + "Linux-X86" | "Linux-X64") + archive="ninja-linux.zip" + ;; + "Linux-ARM64") + archive="ninja-linux-aarch64.zip" + ;; + "macOS-X86" | "macOS-X64" | "macOS-ARM64") + archive="ninja-mac.zip" + ;; + "Windows-X86" | "Windows-X64") + archive="ninja-win.zip" + ;; + "Windows-ARM64") + archive="ninja-winarm64.zip" + ;; + *) + echo "Unsupported ${{ runner.os }}-${{ runner.arch }}" + exit 1; + ;; + esac + echo "archive=${archive}" >> ${GITHUB_OUTPUT} + echo "cache-key=${archive}-${{ inputs.version }}-${{ runner.os }}-${{ runner.arch }}" >> ${GITHUB_OUTPUT} + - name: 'Restore cached ${{ steps.calc.outputs.archive }}' + id: cache-restore + uses: actions/cache/restore@v4 + with: + path: '${{ runner.temp }}/${{ steps.calc.outputs.archive }}' + key: ${{ steps.calc.outputs.cache-key }} + - name: 'Download ninja ${{ inputs.version }} for ${{ runner.os }} (${{ runner.arch }})' + if: ${{ !steps.cache-restore.outputs.cache-hit || steps.cache-restore.outputs.cache-hit == 'false' }} + shell: pwsh + run: | + Invoke-WebRequest "https://github.com/ninja-build/ninja/releases/download/v${{ inputs.version }}/${{ steps.calc.outputs.archive }}" -OutFile "${{ runner.temp }}/${{ steps.calc.outputs.archive }}" + - name: 'Cache ${{ steps.calc.outputs.archive }}' + if: ${{ !steps.cache-restore.outputs.cache-hit || steps.cache-restore.outputs.cache-hit == 'false' }} + uses: actions/cache/save@v4 + with: + path: '${{ runner.temp }}/${{ steps.calc.outputs.archive }}' + key: ${{ steps.calc.outputs.cache-key }} + - name: 'Extract ninja' + shell: pwsh + run: | + 7z "-o${{ runner.temp }}/ninja-${{ inputs.version }}-${{ runner.arch }}" x "${{ runner.temp }}/${{ steps.calc.outputs.archive }}" + - name: 'Set output variables' + id: final + shell: pwsh + run: | + echo "${{ runner.temp }}/ninja-${{ inputs.version }}-${{ runner.arch }}" >> $env:GITHUB_PATH diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 889fbc02b..14e1d239c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -24,12 +24,12 @@ jobs: with: python-version: '3.11' - name: 'Fetch build-release.py' - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: ref: ${{ inputs.commit }} sparse-checkout: 'build-scripts/build-release.py' - name: 'Set up SDL sources' - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: ref: ${{ inputs.commit }} path: 'SDL' @@ -96,40 +96,18 @@ jobs: shell: bash run: | ${{ steps.tar.outputs.path }}/build-scripts/test-versioning.sh - - name: 'Fetch build-release.py' - uses: actions/checkout@v4 + - name: 'Fetch setup-ninja action' + uses: actions/checkout@v5 with: ref: ${{ inputs.commit }} sparse-checkout: | - build-scripts/build-release.py .github/actions/setup-ninja/action.yml - - name: 'Download dependencies' - id: deps - env: - GH_TOKEN: ${{ github.token }} - run: | - python build-scripts/build-release.py \ - --actions download \ - --commit ${{ inputs.commit }} \ - --root "${{ steps.tar.outputs.path }}" \ - --github \ - --debug - - name: 'Install Linux dependencies' - run: | - sudo apt-get update -y - sudo apt-get install -y \ - gnome-desktop-testing libasound2-dev libpulse-dev libaudio-dev libjack-dev libsndio-dev \ - libusb-1.0-0-dev libx11-dev libxext-dev libxrandr-dev libxcursor-dev libxfixes-dev libxi-dev \ - libxss-dev libwayland-dev libxkbcommon-dev libdrm-dev libgbm-dev libgl1-mesa-dev libgles2-mesa-dev \ - libegl1-mesa-dev libdbus-1-dev libibus-1.0-dev libudev-dev fcitx-libs-dev - - name: 'Extract dependencies, build and install them' - id: deps-build - run: | - tar -C /tmp -v -x -f "${{ steps.deps.outputs.dep-path }}/SDL3-${{ steps.deps.outputs.dep-sdl-version }}.tar.gz" - cmake -S /tmp/SDL3-${{ steps.deps.outputs.dep-sdl-version }} -B /tmp/SDL-build -DSDL_UNIX_CONSOLE_BUILD=ON -DCMAKE_INSTALL_PREFIX=/tmp/deps-prefix - cmake --build /tmp/SDL-build - cmake --install /tmp/SDL-build - echo "path=/tmp/deps-prefix" >>$GITHUB_OUTPUT + - name: 'Setup sdl2-compat' + uses: libsdl-org/setup-sdl@main + with: + version: 3-latest + version-sdl2-compat: 2-latest + install-linux-dependencies: true - name: Set up ninja uses: ./.github/actions/setup-ninja - name: 'CMake (configure + build)' @@ -137,8 +115,7 @@ jobs: cmake \ -GNinja \ -S ${{ steps.tar.outputs.path }} \ - -B /tmp/build \ - -DCMAKE_PREFIX_PATH="${{ steps.deps-build.outputs.path }}" + -B /tmp/build cmake --build /tmp/build --verbose # ctest --test-dir /tmp/build --no-tests=error --output-on-failure @@ -153,7 +130,7 @@ jobs: # with: # python-version: '3.11' # - name: 'Fetch build-release.py' -# uses: actions/checkout@v4 +# uses: actions/checkout@v5 # with: # ref: ${{ inputs.commit }} # sparse-checkout: 'build-scripts/build-release.py' @@ -201,7 +178,7 @@ jobs: # with: # python-version: '3.11' # - name: 'Fetch build-release.py' -# uses: actions/checkout@v4 +# uses: actions/checkout@v5 # with: # ref: ${{ inputs.commit }} # sparse-checkout: 'build-scripts/build-release.py' @@ -343,7 +320,7 @@ jobs: with: python-version: '3.11' - name: 'Fetch build-release.py' - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: ref: ${{ inputs.commit }} sparse-checkout: 'build-scripts/build-release.py' @@ -384,7 +361,7 @@ jobs: runs-on: windows-latest steps: - name: 'Fetch .github/actions/setup-ninja/action.yml' - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: ref: ${{ inputs.commit }} sparse-checkout: | @@ -408,24 +385,6 @@ jobs: cd '${{ github.workspace }}/sources' unzip "${{ github.workspace }}/${{ needs.src.outputs.src-zip }}" echo "path=${{ github.workspace }}/sources/${{ needs.src.outputs.project }}-${{ needs.src.outputs.version }}" >>$env:GITHUB_OUTPUT - - name: 'Download dependencies' - id: deps - env: - GH_TOKEN: ${{ github.token }} - run: | - python build-scripts/build-release.py ` - --actions download ` - --commit ${{ inputs.commit }} ` - --root "${{ steps.src.outputs.path }}" ` - --github ` - --debug - - name: 'Extract dependencies' - id: deps-extract - run: | - mkdir '${{ github.workspace }}/deps-vc' - cd '${{ github.workspace }}/deps-vc' - unzip "${{ steps.deps.outputs.dep-path }}/SDL3-devel-${{ steps.deps.outputs.dep-sdl-version }}-VC.zip" - echo "path=${{ github.workspace }}/deps-vc" >>$env:GITHUB_OUTPUT - name: 'Download MSVC binaries' uses: actions/download-artifact@v4 with: @@ -444,7 +403,7 @@ jobs: arch: x64_x86 - name: 'CMake (configure + build + tests) x86' run: | - cmake -S "${{ steps.src.outputs.path }}/cmake/test" ` + cmake -S "${{ steps.src.outputs.path }}/test" ` -B build_x86 ` -GNinja ` -DCMAKE_BUILD_TYPE=Debug ` @@ -452,7 +411,7 @@ jobs: -DTEST_SHARED=TRUE ` -DTEST_STATIC=FALSE ` -DCMAKE_SUPPRESS_REGENERATION=TRUE ` - -DCMAKE_PREFIX_PATH="${{ steps.bin.outputs.path }};${{ steps.deps-extract.outputs.path }}" + -DCMAKE_PREFIX_PATH="${{ steps.bin.outputs.path }}" Start-Sleep -Seconds 2 cmake --build build_x86 --config Release --verbose - name: 'Configure vcvars x64' @@ -461,7 +420,7 @@ jobs: arch: x64 - name: 'CMake (configure + build + tests) x64' run: | - cmake -S "${{ steps.src.outputs.path }}/cmake/test" ` + cmake -S "${{ steps.src.outputs.path }}/test" ` -B build_x64 ` -GNinja ` -DCMAKE_BUILD_TYPE=Debug ` @@ -469,7 +428,7 @@ jobs: -DTEST_SHARED=TRUE ` -DTEST_STATIC=FALSE ` -DCMAKE_SUPPRESS_REGENERATION=TRUE ` - -DCMAKE_PREFIX_PATH="${{ steps.bin.outputs.path }};${{ steps.deps-extract.outputs.path }}" + -DCMAKE_PREFIX_PATH="${{ steps.bin.outputs.path }}" Start-Sleep -Seconds 2 cmake --build build_x64 --config Release --verbose # - name: 'Configure vcvars arm64' @@ -502,7 +461,7 @@ jobs: # with: # python-version: '3.11' # - name: 'Fetch build-release.py' -# uses: actions/checkout@v4 +# uses: actions/checkout@v5 # with: # ref: ${{ inputs.commit }} # sparse-checkout: 'build-scripts/build-release.py' @@ -550,7 +509,7 @@ jobs: # with: # python-version: '3.11' # - name: 'Fetch build-release.py' -# uses: actions/checkout@v4 +# uses: actions/checkout@v5 # with: # ref: ${{ inputs.commit }} # sparse-checkout: 'build-scripts/build-release.py' diff --git a/CMakeLists.txt b/CMakeLists.txt index 6094ec958..c1299e662 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ # you can define SDL2_INCLUDE_DIR on the cmdline. For example: # cmake -DSDL2_INCLUDE_DIR=/opt/SDL2/include/SDL2 [other stuff] -cmake_minimum_required(VERSION 3.0.0...4.0) +cmake_minimum_required(VERSION 3.0.0...4.1) project(sdl12_compat VERSION 1.2.69 LANGUAGES C) option(SDL12TESTS "Enable to build SDL-1.2 test programs" ON) @@ -22,8 +22,6 @@ include(CheckIncludeFile) include(CheckCCompilerFlag) include(GNUInstallDirs) -set(CMAKE_SKIP_RPATH TRUE) - if(APPLE) set(OSX_SRCS "src/SDL12_compat_objc.m") set_source_files_properties(${OSX_SRCS} PROPERTIES LANGUAGE C) @@ -53,8 +51,11 @@ set(SDL12COMPAT_SRCS ${WIN32_SRCS} ) add_library(SDL SHARED ${SDL12COMPAT_SRCS}) +add_library(SDL::SDL-shared ALIAS SDL) +add_library(SDL::SDL ALIAS SDL) -find_package(SDL2) +find_package(SDL2 CONFIG) +find_package(SDL2 MODULE) if(NOT SDL2_INCLUDE_DIRS) message(FATAL_ERROR "Could not find SDL2 headers") endif() @@ -136,6 +137,7 @@ return 0; }" IS_X86) set_target_properties(SDL PROPERTIES COMPILE_FLAGS ${MSVC_FLAGS}) set_target_properties(SDL PROPERTIES LINK_FLAGS "/NODEFAULTLIB") # Make sure /RTC1 is disabled: (from SDL2 CMake) + set_property(TARGET SDL PROPERTY MSVC_RUNTIME_CHECKS "") foreach(flag_var CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO) @@ -156,90 +158,19 @@ elseif(WIN32) else() add_library(SDLmain STATIC src/SDLmain/dummy/SDL_dummy_main.c) endif() -target_include_directories(SDLmain PRIVATE "include/SDL") - -if(SDL12TESTS) - if(NOT (WIN32 OR APPLE OR CYGWIN OR HAIKU OR BEOS)) - find_library(MATH_LIBRARY m) - endif() - - find_package(OpenGL COMPONENTS OpenGL) - if(OPENGL_FOUND) - set(HAVE_OPENGL_DEFINE "HAVE_OPENGL") - if(WIN32) - set(OPENGL_gl_LIBRARY "opengl32") - set(OPENGL_opengl_LIBRARY "opengl32") - elseif(APPLE) - set(OPENGL_gl_LIBRARY "-Wl,-framework,OpenGL") - set(OPENGL_opengl_LIBRARY "-Wl,-framework,OpenGL") - endif() - endif() - - macro(test_program _NAME _SRCS) - add_executable(${_NAME} ${_SRCS}) - target_include_directories(${_NAME} PRIVATE "include/SDL") - if(MINGW) - target_link_libraries(${_NAME} mingw32 SDLmain SDL) - else() - target_link_libraries(${_NAME} SDLmain SDL) - endif() - # Turn off MSVC's aggressive C runtime warnings for the old test programs. - if(MSVC) - set_target_properties(${_NAME} PROPERTIES COMPILE_DEFINITIONS "${HAVE_OPENGL_DEFINE};_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE") - elseif(APPLE) - set_target_properties(${_NAME} PROPERTIES COMPILE_DEFINITIONS "${HAVE_OPENGL_DEFINE};GL_SILENCE_DEPRECATION=1") - target_link_libraries(${_NAME} "-Wl,-framework,Cocoa") - else() - set_target_properties(${_NAME} PROPERTIES COMPILE_DEFINITIONS "${HAVE_OPENGL_DEFINE}") - endif() - if(MATH_LIBRARY) - target_link_libraries(${_NAME} ${MATH_LIBRARY}) - endif() - endmacro() - - test_program(checkkeys "test/checkkeys.c") - test_program(graywin "test/graywin.c") - test_program(loopwave "test/loopwave.c") - test_program(testalpha "test/testalpha.c") - test_program(testbitmap "test/testbitmap.c") - test_program(testblitspeed "test/testblitspeed.c") - test_program(testcdrom "test/testcdrom.c") - test_program(testcursor "test/testcursor.c") - test_program(testerror "test/testerror.c") - test_program(testfile "test/testfile.c") - test_program(testgamma "test/testgamma.c") - test_program(testthread "test/testthread.c") - test_program(testiconv "test/testiconv.c") - test_program(testjoystick "test/testjoystick.c") - test_program(testkeys "test/testkeys.c") - test_program(testloadso "test/testloadso.c") - test_program(testlock "test/testlock.c") - test_program(testoverlay "test/testoverlay.c") - test_program(testoverlay2 "test/testoverlay2.c") - test_program(testpalette "test/testpalette.c") - test_program(testplatform "test/testplatform.c") - test_program(testsem "test/testsem.c") - test_program(testsprite "test/testsprite.c") - test_program(testtimer "test/testtimer.c") - test_program(testver "test/testver.c") - test_program(testvidinfo "test/testvidinfo.c") - test_program(testwin "test/testwin.c") - test_program(testwm "test/testwm.c") - test_program(threadwin "test/threadwin.c") - test_program(torturethread "test/torturethread.c") - test_program(testdyngl "test/testdyngl.c") - test_program(testgl "test/testgl.c") - if(OPENGL_FOUND) - if(CMAKE_VERSION VERSION_LESS 3.10 OR NOT OPENGL_opengl_LIBRARY) - target_link_libraries(testgl ${OPENGL_gl_LIBRARY}) - else() - target_link_libraries(testgl ${OPENGL_opengl_LIBRARY}) - endif() +add_library(SDL::SDLmain ALIAS SDLmain) +target_include_directories(SDLmain PUBLIC "$") +target_include_directories(SDLmain PUBLIC "$") +if(MINGW OR CYGWIN) + if(CMAKE_SIZEOF_VOID_P EQUAL 4) + target_link_libraries(SDLmain PUBLIC "$<$,EXECUTABLE>:-Wl,--undefined=_WinMain@16>") + else() + target_link_libraries(SDLmain PUBLIC "$<$,EXECUTABLE>:-Wl,--undefined=WinMain>") endif() +endif() - foreach(fname "icon.bmp" "moose.dat" "picture.xbm" "sail.bmp" "sample.bmp" "sample.wav" "utf8.txt") - file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/test/${fname}" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}") - endforeach(fname) +if(SDL12TESTS) + add_subdirectory(test) endif() install(TARGETS SDL SDLmain @@ -317,6 +248,7 @@ endif() if(STATICDEVEL AND SDL12DEVEL) add_library(SDL-static STATIC ${SDL12COMPAT_SRCS}) + add_library(SDL::SDL-static ALIAS SDL-static) target_include_directories(SDL-static PRIVATE ${SDL2_INCLUDE_DIRS}) set_target_properties(SDL-static PROPERTIES COMPILE_DEFINITIONS "_REENTRANT") target_link_libraries(SDL-static PRIVATE ${CMAKE_DL_LIBS}) diff --git a/build-scripts/build-release.py b/build-scripts/build-release.py index f3faa06c3..d7e7028ec 100755 --- a/build-scripts/build-release.py +++ b/build-scripts/build-release.py @@ -542,6 +542,7 @@ def __init__(self, name: str, ints: tuple[int, ...]): def __repr__(self) -> str: return f"<{self.name} ({'.'.join(str(v) for v in self.ints)})>" +ANDROID_ABI_EXTRA_LINK_OPTIONS = {} class Releaser: def __init__(self, release_info: dict, commit: str, revision: str, root: Path, dist_path: Path, section_printer: SectionPrinter, executer: Executer, cmake_generator: str, deps_path: Path, overwrite: bool, github: bool, fast: bool): @@ -1013,6 +1014,7 @@ def create_android_archives(self, android_api: int, android_home: Path, android_ android_devel_file_tree = ArchiveFileTree() for android_abi in android_abis: + extra_link_options = ANDROID_ABI_EXTRA_LINK_OPTIONS.get(android_abi, "") with self.section_printer.group(f"Building for Android {android_api} {android_abi}"): build_dir = self.root / "build-android" / f"{android_abi}-build" install_dir = self.root / "install-android" / f"{android_abi}-install" @@ -1023,8 +1025,11 @@ def create_android_archives(self, android_api: int, android_home: Path, android_ "cmake", "-S", str(self.root), "-B", str(build_dir), - f'''-DCMAKE_C_FLAGS="-ffile-prefix-map={self.root}=/src/{self.project}"''', - f'''-DCMAKE_CXX_FLAGS="-ffile-prefix-map={self.root}=/src/{self.project}"''', + # NDK 21e does not support -ffile-prefix-map + # f'''-DCMAKE_C_FLAGS="-ffile-prefix-map={self.root}=/src/{self.project}"''', + # f'''-DCMAKE_CXX_FLAGS="-ffile-prefix-map={self.root}=/src/{self.project}"''', + f"-DCMAKE_EXE_LINKER_FLAGS={extra_link_options}", + f"-DCMAKE_SHARED_LINKER_FLAGS={extra_link_options}", f"-DCMAKE_TOOLCHAIN_FILE={cmake_toolchain_file}", f"-DCMAKE_PREFIX_PATH={str(android_deps_path)}", f"-DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=BOTH", @@ -1179,7 +1184,7 @@ def build_msvc(self): with self.section_printer.group("Create SDL VC development zip"): self._build_msvc_devel() - def _build_msvc_msbuild(self, arch_platform: VsArchPlatformConfig, vs: VisualStudio): + def _copy_dep_files(self, arch_platform: VsArchPlatformConfig): platform_context = self.get_context(arch_platform.extra_context()) for dep, depinfo in self.release_info["msvc"].get("dependencies", {}).items(): msvc_zip = self.deps_path / glob.glob(depinfo["artifact"], root_dir=self.deps_path)[0] @@ -1207,6 +1212,9 @@ def _build_msvc_msbuild(self, arch_platform: VsArchPlatformConfig, vs: VisualStu dst.parent.mkdir(exist_ok=True, parents=True) dst.write_bytes(zip_data) + def _build_msvc_msbuild(self, arch_platform: VsArchPlatformConfig, vs: VisualStudio): + self._copy_dep_files(arch_platform) + prebuilt_paths = set(self.root / full_prebuilt_path for prebuilt_path in self.release_info["msvc"]["msbuild"].get("prebuilt", []) for full_prebuilt_path in glob.glob(configure_text(prebuilt_path, context=platform_context), root_dir=self.root)) msbuild_paths = set(self.root / configure_text(f, context=platform_context) for file_mapping in (self.release_info["msvc"]["msbuild"]["files-lib"], self.release_info["msvc"]["msbuild"]["files-devel"]) for files_list in file_mapping.values() for f in files_list) assert prebuilt_paths.issubset(msbuild_paths), f"msvc.msbuild.prebuilt must be a subset of (msvc.msbuild.files-lib, msvc.msbuild.files-devel)" @@ -1276,6 +1284,8 @@ def _build_msvc_cmake(self, arch_platform: VsArchPlatformConfig, dep_roots: list "PLATFORM": arch_platform.platform, } + self._copy_dep_files(arch_platform) + built_paths = set(install_path / configure_text(f, context=platform_context) for file_mapping in (self.release_info["msvc"]["cmake"]["files-lib"], self.release_info["msvc"]["cmake"]["files-devel"]) for files_list in file_mapping.values() for f in files_list) logger.info("CMake builds these files, to be included in the package: %s", built_paths) if not self.fast: @@ -1512,7 +1522,7 @@ def main(argv=None) -> int: if args.android_home is None or not Path(args.android_home).is_dir(): parser.error("Invalid $ANDROID_HOME or --android-home: must be a directory containing the Android SDK") if args.android_ndk_home is None or not Path(args.android_ndk_home).is_dir(): - parser.error("Invalid $ANDROID_NDK_HOME or --android_ndk_home: must be a directory containing the Android NDK") + parser.error("Invalid $ANDROID_NDK_HOME or --android-ndk-home: must be a directory containing the Android NDK") if args.android_api is None: with section_printer.group("Detect Android APIS"): args.android_api = releaser._detect_android_api(android_home=args.android_home) @@ -1530,7 +1540,7 @@ def main(argv=None) -> int: parser.error("Invalid --android-api, and/or could not be detected") android_api_path = Path(args.android_home) / f"platforms/{args.android_api.name}" if not android_api_path.is_dir(): - parser.error(f"Android API directory does not exist ({android_api_path})") + logger.warning(f"Android API directory does not exist ({android_api_path})") with section_printer.group("Android arguments"): print(f"android_home = {args.android_home}") print(f"android_ndk_home = {args.android_ndk_home}") diff --git a/build-scripts/release-info.json b/build-scripts/release-info.json index 33f531ac8..ef6b9c60a 100644 --- a/build-scripts/release-info.json +++ b/build-scripts/release-info.json @@ -2,13 +2,9 @@ "name": "sdl12-compat", "remote": "libsdl-org/sdl12-compat", "dependencies": { - "SDL2": { + "sdl2-compat": { "startswith": "2.", - "repo": "libsdl-org/SDL" - }, - "SDL3": { - "startswith": "3.", - "repo": "libsdl-org/SDL" + "repo": "libsdl-org/sdl2-compat" } }, "version": { @@ -20,7 +16,7 @@ "source": { "checks": [ "src/SDL12_compat.c", - "include/SDL/SDL_pixels.h", + "include/SDL/SDL.h", "test/testsprite.c" ] }, @@ -40,19 +36,12 @@ ], "files-lib": { "": [ - "bin/SDL.dll", - "bin/SDL2.dll", - "bin/SDL3.dll" + "bin/SDL.dll" ] }, "files-devel": { "lib/@<@ARCH@>@": [ "bin/SDL.dll", - "bin/SDL2.dll", - "bin/SDL3.dll", - "bin/SDL.pdb", - "bin/SDL2.pdb", - "bin/SDL3.pdb", "lib/SDL.lib", "lib/SDLmain.lib" ] @@ -62,7 +51,9 @@ "": [ "build-scripts/pkg-support/msvc/@<@ARCH@>@/INSTALL.md.in:INSTALL.md", "LICENSE.txt", - "build-scripts/pkg-support/msvc/README.md" + "build-scripts/pkg-support/msvc/README.md", + "@<@ARCH@>@/SDL2.dll", + "@<@ARCH@>@/SDL3.dll" ] }, "files-devel": { @@ -73,14 +64,25 @@ ], "include": [ "include/SDL/*" + ], + "lib/@<@ARCH@>@": [ + "@<@ARCH@>@/SDL2.dll", + "@<@ARCH@>@/SDL3.dll" ] }, "dependencies": { - "SDL2": { - "artifact": "SDL2-devel-*-VC.zip" - }, - "SDL3": { - "artifact": "SDL3-devel-*-VC.zip" + "sdl2-compat": { + "artifact": "sdl2-compat-devel-2.??.??-VC.zip", + "copy": [ + { + "src": "lib/@<@ARCH@>@/SDL3.dll", + "dst": "@<@ARCH@>@" + }, + { + "src": "lib/@<@ARCH@>@/SDL2.dll", + "dst": "@<@ARCH@>@" + } + ] } } } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 000000000..bff2bf2a8 --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,98 @@ +cmake_minimum_required(VERSION 3.0.0...4.0) +project(sdl12_compat_tests C) + +if(NOT TARGET SDL::SDL) + find_package(SDL REQUIRED) +endif() +if(NOT TARGET SDL::SDLmain) + add_library(SDL::SDLmain STATIC IMPORTED) + if(SDLMAIN_LIBRARY) + message("SDLMAIN_LIBRARY=${SDLMAIN_LIBRARY}") + set_property(TARGET SDL::SDLmain PROPERTY IMPORTED_LOCATION "${SDLMAIN_LIBRARY}") + endif() + if(MINGW OR CYGWIN) + if(CMAKE_SIZEOF_VOID_P EQUAL 4) + set_property(TARGET SDL::SDLmain APPEND INTERFACE_LINK_LIBRARIES "$<$,EXECUTABLE>:-Wl,--undefined=_WinMain@16>") + else() + set_property(TARGET SDL::SDLmain APPEND INTERFACE_LINK_LIBRARIES "$<$,EXECUTABLE>:-Wl,--undefined=WinMain>") + endif() + endif() +endif() + +if(NOT (WIN32 OR APPLE OR CYGWIN OR HAIKU OR BEOS)) + find_library(MATH_LIBRARY m) +endif() + +find_package(OpenGL COMPONENTS OpenGL) +if(OPENGL_FOUND) + set(HAVE_OPENGL_DEFINE "HAVE_OPENGL") + if(WIN32) + set(OPENGL_gl_LIBRARY "opengl32") + set(OPENGL_opengl_LIBRARY "opengl32") + elseif(APPLE) + set(OPENGL_gl_LIBRARY "-Wl,-framework,OpenGL") + set(OPENGL_opengl_LIBRARY "-Wl,-framework,OpenGL") + endif() +endif() + +macro(test_program _NAME _SRCS) + add_executable(${_NAME} ${_SRCS}) + target_include_directories(${_NAME} PRIVATE "include/SDL") + target_link_libraries(${_NAME} PRIVATE SDL::SDLmain SDL::SDL) + # Turn off MSVC's aggressive C runtime warnings for the old test programs. + if(MSVC) + set_target_properties(${_NAME} PROPERTIES COMPILE_DEFINITIONS "${HAVE_OPENGL_DEFINE};_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE") + elseif(APPLE) + set_target_properties(${_NAME} PROPERTIES COMPILE_DEFINITIONS "${HAVE_OPENGL_DEFINE};GL_SILENCE_DEPRECATION=1") + target_link_libraries(${_NAME} PRIVATE "-Wl,-framework,Cocoa") + else() + set_target_properties(${_NAME} PROPERTIES COMPILE_DEFINITIONS "${HAVE_OPENGL_DEFINE}") + endif() + if(MATH_LIBRARY) + target_link_libraries(${_NAME} PRIVATE ${MATH_LIBRARY}) + endif() +endmacro() + +test_program(checkkeys "checkkeys.c") +test_program(graywin "graywin.c") +test_program(loopwave "loopwave.c") +test_program(testalpha "testalpha.c") +test_program(testbitmap "testbitmap.c") +test_program(testblitspeed "testblitspeed.c") +test_program(testcdrom "testcdrom.c") +test_program(testcursor "testcursor.c") +test_program(testerror "testerror.c") +test_program(testfile "testfile.c") +test_program(testgamma "testgamma.c") +test_program(testthread "testthread.c") +test_program(testiconv "testiconv.c") +test_program(testjoystick "testjoystick.c") +test_program(testkeys "testkeys.c") +test_program(testloadso "testloadso.c") +test_program(testlock "testlock.c") +test_program(testoverlay "testoverlay.c") +test_program(testoverlay2 "testoverlay2.c") +test_program(testpalette "testpalette.c") +test_program(testplatform "testplatform.c") +test_program(testsem "testsem.c") +test_program(testsprite "testsprite.c") +test_program(testtimer "testtimer.c") +test_program(testver "testver.c") +test_program(testvidinfo "testvidinfo.c") +test_program(testwin "testwin.c") +test_program(testwm "testwm.c") +test_program(threadwin "threadwin.c") +test_program(torturethread "torturethread.c") +test_program(testdyngl "testdyngl.c") +test_program(testgl "testgl.c") +if(OPENGL_FOUND) + if(CMAKE_VERSION VERSION_LESS 3.10 OR NOT OPENGL_opengl_LIBRARY) + target_link_libraries(testgl PRIVATE ${OPENGL_gl_LIBRARY}) + else() + target_link_libraries(testgl PRIVATE ${OPENGL_opengl_LIBRARY}) + endif() +endif() + +foreach(fname "icon.bmp" "moose.dat" "picture.xbm" "sail.bmp" "sample.bmp" "sample.wav" "utf8.txt") + file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/${fname}" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}") +endforeach(fname) From 517b52247e48c6647578981a17f979157c552016 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 28 Oct 2025 07:42:20 -0700 Subject: [PATCH 563/606] Create an OpenGL window if the default renderer is OpenGL This fixes having to recreate the window when creating the renderer. --- src/SDL12_compat.c | 16 ++++++++++++++++ src/SDL20_syms.h | 1 + 2 files changed, 17 insertions(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index e122fd9a0..8dedf514f 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -6342,6 +6342,18 @@ UnlockVideoRenderer(void) static void UpdateInputGrab(void); +static SDL_bool ShouldUseOpenGL(void) +{ + /* Create an OpenGL window if the default renderer is OpenGL */ + SDL_RendererInfo info; + if (SDL20_GetRenderDriverInfo(0, &info) == 0) { + if (SDL20_strncmp(info.name, "opengl", 6) == 0) { + return SDL_TRUE; + } + } + return SDL_FALSE; +} + static SDL12_Surface * SetVideoModeImpl(int width, int height, int bpp, Uint32 flags12) { @@ -6559,6 +6571,10 @@ SetVideoModeImpl(int width, int height, int bpp, Uint32 flags12) if (flags12 & SDL12_NOFRAME) { flags20 |= SDL_WINDOW_BORDERLESS; } if (use_highdpi) { flags20 |= SDL_WINDOW_ALLOW_HIGHDPI; } + if (!(flags20 & SDL_WINDOW_OPENGL) && ShouldUseOpenGL()) { + flags20 |= SDL_WINDOW_OPENGL; + } + /* most platforms didn't check these environment variables, but the major ones did (x11, windib, quartz), so we'll just offer it everywhere. */ GetEnvironmentWindowPosition(&x, &y); diff --git a/src/SDL20_syms.h b/src/SDL20_syms.h index f11de4589..ab7572d1b 100644 --- a/src/SDL20_syms.h +++ b/src/SDL20_syms.h @@ -319,6 +319,7 @@ SDL20_SYM(double,fabs,(double a),(a),return) SDL20_SYM(double,ceil,(double a),(a),return) SDL20_SYM(double,floor,(double a),(a),return) +SDL20_SYM(int,GetRenderDriverInfo,(int a, SDL_RendererInfo *b),(a,b),return) SDL20_SYM(SDL_Renderer *,CreateRenderer,(SDL_Window *a, int b, Uint32 c),(a,b,c),return) SDL20_SYM(int,GetRendererInfo,(SDL_Renderer *a, SDL_RendererInfo *b),(a,b),return) SDL20_SYM(void,RenderGetScale,(SDL_Renderer *a, float *b, float *c),(a,b,c),return) From 8f3c4493a43f479ab928e86070a41ede22f33576 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 28 Oct 2025 07:58:26 -0700 Subject: [PATCH 564/606] Fixed recreating non-OpenGL X11 windows on every mode change --- src/SDL12_compat.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 8dedf514f..4972cc00f 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -6500,7 +6500,6 @@ SetVideoModeImpl(int width, int height, int bpp, Uint32 flags12) */ const SDL_bool recreate_window = ( ((VideoSurface12->flags & SDL12_OPENGL) != (flags12 & SDL12_OPENGL)) || - ((flags12 & SDL12_OPENGL) != SDL12_OPENGL) || (!VideoSurface12->format || (VideoSurface12->format->BitsPerPixel != bpp)) || ((VideoSurface12->flags & SDL12_NOFRAME) != (flags12 & SDL12_NOFRAME)) ) ? SDL_TRUE : SDL_FALSE; From 1a1944b1e0b1d9f6aa9db70abcb254a92d363409 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 28 Oct 2025 11:40:27 -0400 Subject: [PATCH 565/606] quirks: Jamestown doesn't work with OpenGL scaling. Fixes #337. --- src/SDL12_compat.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 4972cc00f..eea0f685c 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1454,7 +1454,12 @@ static QuirkEntryType quirks[] = { /* Loki Unreal Tournament '99 runs at hyperspeed if the framerate is too high. Force it to vsync. You should use the newer OldUnreal binaries with SDL2 instead! */ {"ut-bin", "SDL12COMPAT_SYNC_TO_VBLANK", "1"}, - {"ut-bin", "SDL12COMPAT_MAX_FPS", "120"} + {"ut-bin", "SDL12COMPAT_MAX_FPS", "120"}, + + /* Jamestown (the old Humble Bundle version from 2011) doesn't render in-game with GL scaling enabled. */ + {"Jamestown-x86", "SDL12COMPAT_OPENGL_SCALING", "0"}, + {"Jamestown-amd64", "SDL12COMPAT_OPENGL_SCALING", "0"}, + #else /* TODO: Add any quirks needed for this system. */ From 4185ef5b11a719ff0fc6b7804212e0ef05b276e2 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 28 Oct 2025 09:50:24 -0700 Subject: [PATCH 566/606] Fixed recreating the window during resize on Windows --- src/SDL12_compat.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index eea0f685c..bcec26858 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -6483,10 +6483,10 @@ SetVideoModeImpl(int width, int height, int bpp, Uint32 flags12) * - window is already SDL_OPENGL. * - window is not a fullscreen window. */ + const Uint32 important_flags = ~(SDL12_PREALLOC | SDL12_ANYFORMAT); const SDL_bool recreate_window = ( - ((VideoSurface12->flags & ~SDL12_ANYFORMAT) != (flags12 & ~SDL12_ANYFORMAT)) || + ((VideoSurface12->flags & important_flags) != (flags12 & important_flags)) || (!VideoSurface12->format || (VideoSurface12->format->BitsPerPixel != bpp)) || - ((flags12 & SDL12_OPENGL) != SDL12_OPENGL) || ((flags12 & SDL12_FULLSCREEN) == SDL12_FULLSCREEN) ) ? SDL_TRUE : SDL_FALSE; #elif defined(__APPLE__) From 03cd2f428b6ad73a83ec752526b2552cc0303886 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 28 Oct 2025 10:08:02 -0700 Subject: [PATCH 567/606] Send only a single resize event at the end of window resizing on Windows Because we're using an event hook we get all the resize events that are queued up during a resize operation, so make sure we only dispatch a resize once at the end, like SDL 1.2 does. --- src/SDL12_compat.c | 40 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index bcec26858..68051848c 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1066,6 +1066,10 @@ static SDL_bool PreserveDestinationAlpha = SDL_TRUE; static int DesiredRefreshRate = SDL12_REFRESH_DEFAULT; static int CurrentRefreshRate = SDL12_REFRESH_DEFAULT; +static int ProcessingModalLoop; +static SDL_bool HasPendingResizeEvent; +static SDL12_Event PendingResizeEvent; + /* This is a KEYDOWN event which is being held for a follow-up TEXTINPUT */ static SDL12_Event PendingKeydownEvent; @@ -2692,7 +2696,11 @@ Init12Video(void) SDL20_memset(EventStates, SDL_ENABLE, sizeof (EventStates)); /* on by default */ EventStates[SDL12_SYSWMEVENT] = SDL_IGNORE; /* off by default. */ +#if defined(SDL_VIDEO_DRIVER_WINDOWS) + SDL20_EventState(SDL_SYSWMEVENT, SDL_ENABLE); +#else SDL20_EventState(SDL_SYSWMEVENT, SDL_IGNORE); +#endif #if defined(SDL_VIDEO_DRIVER_WINDOWS) SupportSysWM = (SDL20_strcmp(driver, "windows") == 0) ? SDL_TRUE : SDL_FALSE; @@ -4858,9 +4866,16 @@ EventFilter20to12(void *data, SDL_Event *event20) break; } - event12.type = SDL12_VIDEORESIZE; - event12.resize.w = event20->window.data1; - event12.resize.h = event20->window.data2; + if (ProcessingModalLoop) { + PendingResizeEvent.type = SDL12_VIDEORESIZE; + PendingResizeEvent.resize.w = event20->window.data1; + PendingResizeEvent.resize.h = event20->window.data2; + HasPendingResizeEvent = SDL_TRUE; + } else { + event12.type = SDL12_VIDEORESIZE; + event12.resize.w = event20->window.data1; + event12.resize.h = event20->window.data2; + } break; } @@ -4903,6 +4918,25 @@ EventFilter20to12(void *data, SDL_Event *event20) break; case SDL_SYSWMEVENT: + #if defined(SDL_VIDEO_DRIVER_WINDOWS) + switch (event20->syswm.msg->msg.win.msg) { + case WM_ENTERSIZEMOVE: + case WM_ENTERMENULOOP: + ++ProcessingModalLoop; + break; + case WM_EXITSIZEMOVE: + case WM_EXITMENULOOP: + --ProcessingModalLoop; + if (ProcessingModalLoop == 0 && HasPendingResizeEvent) { + PushEventIfNotFiltered(&PendingResizeEvent); + HasPendingResizeEvent = SDL_FALSE; + } + break; + default: + break; + } + #endif + if (!SupportSysWM) { return 1; } From b8f62b7ca846c2274a63eb27525ffb284e2b4480 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Tue, 28 Oct 2025 20:37:00 +0300 Subject: [PATCH 568/606] fix build using c++ compilers. --- src/SDL12_compat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 68051848c..3fdc4b1af 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -7777,7 +7777,7 @@ UpdateInputGrab(void) /* SDL 1.2 always grabbed input if the video mode was fullscreen. */ if (VideoWindow20) { const SDL_bool isfullscreen = (VideoSurface12 && VideoSurface12->surface20 && (VideoSurface12->flags & SDL12_FULLSCREEN)) ? SDL_TRUE : SDL_FALSE; - const SDL_bool wantgrab = (VideoWindowGrabWanted || isfullscreen); + const SDL_bool wantgrab = (VideoWindowGrabWanted || isfullscreen) ? SDL_TRUE : SDL_FALSE; SDL20_SetWindowGrab(VideoWindow20, wantgrab); VideoWindowGrabbed = wantgrab; UpdateRelativeMouseMode(); From 49908817d9b4c4044116a1db65587e63f31e85f2 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 28 Oct 2025 11:06:43 -0700 Subject: [PATCH 569/606] Added support for right modifiers and menu key on Windows --- src/SDL12_compat.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 3fdc4b1af..fb1d3099e 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -4648,6 +4648,7 @@ Scancode20to12(SDL_Scancode sc) CASESCANCODE20TO12(9, 0x12, 0x19); CASESCANCODE20TO12(A, 0x26, 0x00); CASESCANCODE20TO12(APOSTROPHE, 0x30, 0x27); + CASESCANCODE20TO12(APPLICATION, 0x65, 0x00); CASESCANCODE20TO12(B, 0x38, 0x0B); CASESCANCODE20TO12(BACKSLASH, 0x33, 0x2A); CASESCANCODE20TO12(BACKSPACE, 0x16, 0x33); @@ -4707,6 +4708,7 @@ Scancode20to12(SDL_Scancode sc) CASESCANCODE20TO12(LGUI, 0x85, 0x00); CASESCANCODE20TO12(LSHIFT, 0x32, 0x00); CASESCANCODE20TO12(M, 0x3A, 0x2E); + CASESCANCODE20TO12(MENU, 0x65, 0x00); CASESCANCODE20TO12(MINUS, 0x14, 0x1B); CASESCANCODE20TO12(N, 0x39, 0x2D); /* On Macs with ANSI layout, 0x32 is SDL_SCANCODE_GRAVE and _NONUSBACKSLASH doesn't exist. @@ -4724,6 +4726,8 @@ Scancode20to12(SDL_Scancode sc) CASESCANCODE20TO12(Q, 0x18, 0x0C); CASESCANCODE20TO12(R, 0x1B, 0x0F); CASESCANCODE20TO12(RETURN, 0x24, 0x24); + CASESCANCODE20TO12(RALT, 0x40, 0x00); + CASESCANCODE20TO12(RCTRL, 0x25, 0x00); CASESCANCODE20TO12(RGUI, 0x86, 0x00); CASESCANCODE20TO12(RIGHT, 0x00, 0x7C); CASESCANCODE20TO12(RIGHTBRACKET, 0x23, 0x1E); From 6664980e293123ca0d61eb5ef9f78ad844adf454 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 28 Oct 2025 11:13:12 -0700 Subject: [PATCH 570/606] Map SDL2 SDLK_APPLICATION to SDL12 SDLK_MENU Fixes https://github.com/libsdl-org/sdl12-compat/issues/351 --- src/SDL12_compat.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index fb1d3099e..359ab4ec0 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -3764,6 +3764,7 @@ Keysym20to12(const SDL_Keycode keysym20) CASEKEYSYM20TO12(RGUI, RMETA); CASEKEYSYM20TO12(LGUI, LMETA); CASEKEYSYM20TO12(PRINTSCREEN, PRINT); + CASEKEYSYM20TO12(APPLICATION, MENU); #undef CASEKEYSYM20TO12 #define CASEKEYSYM20TO12(k) case SDLK_##k: return SDLK12_##k From eee7543e7ac9c0ea91fd28674f92bcefd0746bf8 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Wed, 29 Oct 2025 12:26:24 -0700 Subject: [PATCH 571/606] Updated to version 1.2.70 for release --- CMakeLists.txt | 4 ++-- include/SDL/SDL_version.h | 2 +- src/Makefile.darwin | 2 +- src/Makefile.linux | 2 +- src/Makefile.os2 | 2 +- src/Makefile.w32 | 2 +- src/SDL12_compat.c | 2 +- src/version.rc | 8 ++++---- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c1299e662..67d6bb268 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ # cmake -DSDL2_INCLUDE_DIR=/opt/SDL2/include/SDL2 [other stuff] cmake_minimum_required(VERSION 3.0.0...4.1) -project(sdl12_compat VERSION 1.2.69 LANGUAGES C) +project(sdl12_compat VERSION 1.2.70 LANGUAGES C) option(SDL12TESTS "Enable to build SDL-1.2 test programs" ON) option(SDL12DEVEL "Enable installing SDL-1.2 development headers" ON) @@ -33,7 +33,7 @@ if(APPLE) # Xcode project file uses 1.0.0, but it's more compatible to use the # higher version. set(DYLIB_COMPAT_VERSION 12.0.0 CACHE STRING "library compatibility version") - set(DYLIB_CURRENT_VERSION 12.69.0 CACHE STRING "library current version") + set(DYLIB_CURRENT_VERSION 12.70.0 CACHE STRING "library current version") include_directories("/opt/X11/include") # hack. if(CMAKE_VERSION VERSION_LESS 3.9) else() diff --git a/include/SDL/SDL_version.h b/include/SDL/SDL_version.h index 6e198bd92..5108266a3 100644 --- a/include/SDL/SDL_version.h +++ b/include/SDL/SDL_version.h @@ -33,7 +33,7 @@ real SDL-1.2 available to you. */ /* We bumped the patchlevel to 50 for sdl12-compat */ #define SDL_MAJOR_VERSION 1 #define SDL_MINOR_VERSION 2 -#define SDL_PATCHLEVEL 69 +#define SDL_PATCHLEVEL 70 typedef struct SDL_version { diff --git a/src/Makefile.darwin b/src/Makefile.darwin index ff8ca112f..85cb4a76d 100644 --- a/src/Makefile.darwin +++ b/src/Makefile.darwin @@ -18,7 +18,7 @@ CFLAGS = -mmacosx-version-min=10.6 -fPIC -O3 -Wall LDFLAGS = -mmacosx-version-min=10.6 -dynamiclib -Wl,-undefined,error -Wl,-single_module #LDFLAGS+= -Wl,-headerpad_max_install_names LDFLAGS+= -Wl,-install_name,"/usr/local/lib/$(DYLIB)" -LDFLAGS+= -Wl,-compatibility_version,1.0 -Wl,-current_version,12.69 +LDFLAGS+= -Wl,-compatibility_version,1.0 -Wl,-current_version,12.70 LDLIBS = -Wl,-framework,AppKit # this is needed for x86_64 - cross-gcc might not add it. #LDLIBS += -Wl,-lbundle1.o diff --git a/src/Makefile.linux b/src/Makefile.linux index 88e9c26a0..0fdfd4c77 100644 --- a/src/Makefile.linux +++ b/src/Makefile.linux @@ -16,7 +16,7 @@ LDFLAGS = -shared -Wl,-soname,libSDL-1.2.so.0 LDFLAGS+= -Wl,--no-undefined LDLIBS = -ldl -SHLIB = libSDL-1.2.so.1.2.69 +SHLIB = libSDL-1.2.so.1.2.70 OBJ = SDL12_compat.o diff --git a/src/Makefile.os2 b/src/Makefile.os2 index d5bb49c72..26e503f3a 100644 --- a/src/Makefile.os2 +++ b/src/Makefile.os2 @@ -5,7 +5,7 @@ !endif DLLNAME = SDL12 -VERSION = 1.2.69 +VERSION = 1.2.70 # change SDL2INC to point to the SDL2 headers SDL2INC = include diff --git a/src/Makefile.w32 b/src/Makefile.w32 index 83c5e8ffc..a01ec9644 100644 --- a/src/Makefile.w32 +++ b/src/Makefile.w32 @@ -5,7 +5,7 @@ !endif DLLNAME = SDL -VERSION = 1.2.69 +VERSION = 1.2.70 # change SDL2INC to point to the SDL2 headers SDL2INC = include diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 359ab4ec0..f54f60e9b 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -28,7 +28,7 @@ * should be way ahead of what SDL-1.2 Classic would report, so apps can * decide if they're running under the compat layer, if they really care. */ -#define SDL12_COMPAT_VERSION 69 +#define SDL12_COMPAT_VERSION 70 #include #include diff --git a/src/version.rc b/src/version.rc index cb670e1b9..08229fade 100644 --- a/src/version.rc +++ b/src/version.rc @@ -3,8 +3,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,2,69,0 - PRODUCTVERSION 1,2,69,0 + FILEVERSION 1,2,70,0 + PRODUCTVERSION 1,2,70,0 FILEFLAGSMASK 0x3fL FILEFLAGS 0x0L FILEOS 0x40004L @@ -17,12 +17,12 @@ BEGIN BEGIN VALUE "CompanyName", "\0" VALUE "FileDescription", "SDL\0" - VALUE "FileVersion", "1, 2, 69, 0\0" + VALUE "FileVersion", "1, 2, 70, 0\0" VALUE "InternalName", "SDL\0" VALUE "LegalCopyright", "Copyright (C) 2025 Sam Lantinga\0" VALUE "OriginalFilename", "SDL.dll\0" VALUE "ProductName", "Simple DirectMedia Layer 1.2 wrapper\0" - VALUE "ProductVersion", "1, 2, 69, 0\0" + VALUE "ProductVersion", "1, 2, 70, 0\0" END END BLOCK "VarFileInfo" From 9fb466ec58119d12bd2bce47e8810cb282104bd8 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Thu, 30 Oct 2025 12:45:00 +0000 Subject: [PATCH 572/606] test: Optionally install manual tests for "as-installed" testing This provides a convenient way to install manual tests onto a test system. For example in Debian these are packaged into the libsdl1.2-compat-tests binary package, from which they can be run with commands like: cd /usr/libexec/installed-tests/SDL12_compat ./testoverlay2 (The path used was historically /usr/libexec/installed-tests/libsdl1.2-compat, but this version uses a path that is more consistent with SDL2_compat.) Signed-off-by: Simon McVittie --- test/CMakeLists.txt | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index bff2bf2a8..b23b88ef0 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -19,6 +19,11 @@ if(NOT TARGET SDL::SDLmain) endif() endif() +option(SDL12COMPAT_INSTALL_TESTS "Install manual tests into libexecdir" OFF) + +set(SDL12COMPAT_TEST_EXECUTABLES) +set(SDL12COMPAT_TEST_RESOURCE_FILES) + if(NOT (WIN32 OR APPLE OR CYGWIN OR HAIKU OR BEOS)) find_library(MATH_LIBRARY m) endif() @@ -37,6 +42,7 @@ endif() macro(test_program _NAME _SRCS) add_executable(${_NAME} ${_SRCS}) + list(APPEND SDL12COMPAT_TEST_EXECUTABLES ${_NAME}) target_include_directories(${_NAME} PRIVATE "include/SDL") target_link_libraries(${_NAME} PRIVATE SDL::SDLmain SDL::SDL) # Turn off MSVC's aggressive C runtime warnings for the old test programs. @@ -95,4 +101,16 @@ endif() foreach(fname "icon.bmp" "moose.dat" "picture.xbm" "sail.bmp" "sample.bmp" "sample.wav" "utf8.txt") file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/${fname}" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}") + list(APPEND SDL12COMPAT_TEST_RESOURCE_FILES "${fname}") endforeach(fname) + +if(SDL12COMPAT_INSTALL_TESTS) + install( + TARGETS ${SDL12COMPAT_TEST_EXECUTABLES} + DESTINATION ${CMAKE_INSTALL_LIBEXECDIR}/installed-tests/SDL12_compat + ) + install( + FILES ${SDL12COMPAT_TEST_RESOURCE_FILES} + DESTINATION ${CMAKE_INSTALL_LIBEXECDIR}/installed-tests/SDL12_compat + ) +endif() From 8c181ec9ae73962eac2981d3db894f066fb54693 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 30 Oct 2025 11:08:06 -0700 Subject: [PATCH 573/606] Updated to version 1.2.71 for development --- CMakeLists.txt | 4 ++-- include/SDL/SDL_version.h | 2 +- src/Makefile.darwin | 2 +- src/Makefile.linux | 2 +- src/Makefile.os2 | 2 +- src/Makefile.w32 | 2 +- src/SDL12_compat.c | 2 +- src/version.rc | 8 ++++---- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 67d6bb268..bf355079e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ # cmake -DSDL2_INCLUDE_DIR=/opt/SDL2/include/SDL2 [other stuff] cmake_minimum_required(VERSION 3.0.0...4.1) -project(sdl12_compat VERSION 1.2.70 LANGUAGES C) +project(sdl12_compat VERSION 1.2.71 LANGUAGES C) option(SDL12TESTS "Enable to build SDL-1.2 test programs" ON) option(SDL12DEVEL "Enable installing SDL-1.2 development headers" ON) @@ -33,7 +33,7 @@ if(APPLE) # Xcode project file uses 1.0.0, but it's more compatible to use the # higher version. set(DYLIB_COMPAT_VERSION 12.0.0 CACHE STRING "library compatibility version") - set(DYLIB_CURRENT_VERSION 12.70.0 CACHE STRING "library current version") + set(DYLIB_CURRENT_VERSION 12.71.0 CACHE STRING "library current version") include_directories("/opt/X11/include") # hack. if(CMAKE_VERSION VERSION_LESS 3.9) else() diff --git a/include/SDL/SDL_version.h b/include/SDL/SDL_version.h index 5108266a3..2f9a4d132 100644 --- a/include/SDL/SDL_version.h +++ b/include/SDL/SDL_version.h @@ -33,7 +33,7 @@ real SDL-1.2 available to you. */ /* We bumped the patchlevel to 50 for sdl12-compat */ #define SDL_MAJOR_VERSION 1 #define SDL_MINOR_VERSION 2 -#define SDL_PATCHLEVEL 70 +#define SDL_PATCHLEVEL 71 typedef struct SDL_version { diff --git a/src/Makefile.darwin b/src/Makefile.darwin index 85cb4a76d..73cc50919 100644 --- a/src/Makefile.darwin +++ b/src/Makefile.darwin @@ -18,7 +18,7 @@ CFLAGS = -mmacosx-version-min=10.6 -fPIC -O3 -Wall LDFLAGS = -mmacosx-version-min=10.6 -dynamiclib -Wl,-undefined,error -Wl,-single_module #LDFLAGS+= -Wl,-headerpad_max_install_names LDFLAGS+= -Wl,-install_name,"/usr/local/lib/$(DYLIB)" -LDFLAGS+= -Wl,-compatibility_version,1.0 -Wl,-current_version,12.70 +LDFLAGS+= -Wl,-compatibility_version,1.0 -Wl,-current_version,12.71 LDLIBS = -Wl,-framework,AppKit # this is needed for x86_64 - cross-gcc might not add it. #LDLIBS += -Wl,-lbundle1.o diff --git a/src/Makefile.linux b/src/Makefile.linux index 0fdfd4c77..483ad2e18 100644 --- a/src/Makefile.linux +++ b/src/Makefile.linux @@ -16,7 +16,7 @@ LDFLAGS = -shared -Wl,-soname,libSDL-1.2.so.0 LDFLAGS+= -Wl,--no-undefined LDLIBS = -ldl -SHLIB = libSDL-1.2.so.1.2.70 +SHLIB = libSDL-1.2.so.1.2.71 OBJ = SDL12_compat.o diff --git a/src/Makefile.os2 b/src/Makefile.os2 index 26e503f3a..c948f5ae7 100644 --- a/src/Makefile.os2 +++ b/src/Makefile.os2 @@ -5,7 +5,7 @@ !endif DLLNAME = SDL12 -VERSION = 1.2.70 +VERSION = 1.2.71 # change SDL2INC to point to the SDL2 headers SDL2INC = include diff --git a/src/Makefile.w32 b/src/Makefile.w32 index a01ec9644..16054bdc4 100644 --- a/src/Makefile.w32 +++ b/src/Makefile.w32 @@ -5,7 +5,7 @@ !endif DLLNAME = SDL -VERSION = 1.2.70 +VERSION = 1.2.71 # change SDL2INC to point to the SDL2 headers SDL2INC = include diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index f54f60e9b..aee55c4d2 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -28,7 +28,7 @@ * should be way ahead of what SDL-1.2 Classic would report, so apps can * decide if they're running under the compat layer, if they really care. */ -#define SDL12_COMPAT_VERSION 70 +#define SDL12_COMPAT_VERSION 71 #include #include diff --git a/src/version.rc b/src/version.rc index 08229fade..7e4d60383 100644 --- a/src/version.rc +++ b/src/version.rc @@ -3,8 +3,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,2,70,0 - PRODUCTVERSION 1,2,70,0 + FILEVERSION 1,2,71,0 + PRODUCTVERSION 1,2,71,0 FILEFLAGSMASK 0x3fL FILEFLAGS 0x0L FILEOS 0x40004L @@ -17,12 +17,12 @@ BEGIN BEGIN VALUE "CompanyName", "\0" VALUE "FileDescription", "SDL\0" - VALUE "FileVersion", "1, 2, 70, 0\0" + VALUE "FileVersion", "1, 2, 71, 0\0" VALUE "InternalName", "SDL\0" VALUE "LegalCopyright", "Copyright (C) 2025 Sam Lantinga\0" VALUE "OriginalFilename", "SDL.dll\0" VALUE "ProductName", "Simple DirectMedia Layer 1.2 wrapper\0" - VALUE "ProductVersion", "1, 2, 70, 0\0" + VALUE "ProductVersion", "1, 2, 71, 0\0" END END BLOCK "VarFileInfo" From 216d766c5bd6350c30393226ab8e4a8d14d5d0b3 Mon Sep 17 00:00:00 2001 From: Petar Popovic Date: Thu, 30 Oct 2025 23:05:50 +0100 Subject: [PATCH 574/606] Install sdl.m4 to target dir instead of full dir --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bf355079e..f4c83332e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -243,7 +243,7 @@ if(SDL12DEVEL) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libSDL${SOPOSTFIX}${SOEXT} DESTINATION "${CMAKE_INSTALL_LIBDIR}") endif() - install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/sdl.m4" DESTINATION "${CMAKE_INSTALL_FULL_DATAROOTDIR}/aclocal") + install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/sdl.m4" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/aclocal") endif() if(STATICDEVEL AND SDL12DEVEL) From b667924b02211dc5b259c27392a75ee72802d553 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Mon, 3 Nov 2025 08:11:58 -0800 Subject: [PATCH 575/606] Re-try creating the window if it failed due to missing OpenGL OpenGL isn't available when using the dummy video driver or if OpenGL isn't installed. Fixes https://github.com/libsdl-org/sdl12-compat/issues/380 --- src/SDL12_compat.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index aee55c4d2..ba5e25522 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -6629,6 +6629,11 @@ SetVideoModeImpl(int width, int height, int bpp, Uint32 flags12) } VideoWindow20 = SDL20_CreateWindow(WindowTitle, x, y, scaled_width, scaled_height, flags20); + if (!VideoWindow20 && (flags20 & SDL_WINDOW_OPENGL) && !(flags12 & SDL12_OPENGL)) { + /* OpenGL might not be installed, try again without that flag */ + flags20 &= ~SDL_WINDOW_OPENGL; + VideoWindow20 = SDL20_CreateWindow(WindowTitle, x, y, scaled_width, scaled_height, flags20); + } if (!VideoWindow20) { return EndVidModeCreate(); } From 57847a9ee21e7f6fb5ea0a1c88c423edac87b17a Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 4 Nov 2025 11:03:17 -0500 Subject: [PATCH 576/606] env: Deal with environment variables in the 1.2 way. There was no Hint API, so environment variables might change on the fly as apps needed different things. SDL3 (an thus, sdl2-compat) will ignore envvar changes after startup, since it copies the OS environment table to an SDL_Environment, and will miss these later changes. So sdl12-compat will use the "unsafe" (that is: not thread safe) methods to pull in environment variables, ignoring SDL2's SDL_getenv, and will take measures to explicitly set hints that SDL2 and later might need, so they are seen internally despite the state of the SDL3 internal SDL_Environment table. Reference Issue https://github.com/libsdl-org/sdl2-compat/issues/540 --- src/SDL12_compat.c | 107 +++++++++++++++++++++++++-------------------- src/SDL20_syms.h | 3 +- 2 files changed, 62 insertions(+), 48 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index ba5e25522..fab38d40b 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1181,22 +1181,20 @@ static SDL_bool SDL12COMPAT_strequal(const char *a, const char *b) return SDL_TRUE; } -/* log a string using platform-specific code for before SDL2 is fully available. */ -static void SDL12COMPAT_LogAtStartup(const char *str) +/* SDL3 (and thus sdl2-compat) will build an SDL_Environment, which isn't useful if the SDL-1.2 app is calling getenv()/setenv() directly, so use system APIs instead. */ +/* despite the "unsafe" name (they are NOT thread-safe), these are actually _safe_ to call at startup, since it won't call into SDL2 before everything is properly initialized! */ +static char *SDL12COMPAT_getenv_unsafe(const char *name) { #ifdef _WIN32 - OutputDebugStringA(str); - #elif defined(__APPLE__) - extern void SDL12COMPAT_NSLog(const char *prefix, const char *text); - SDL12COMPAT_NSLog(NULL, str); - #else - fputs(str, stderr); - fputs("\n", stderr); + static char buf[256]; /* overflows will just report as environment variable being unset. But most of our environment vars don't come through here. */ + const DWORD rc = GetEnvironmentVariableA(name, buf, (DWORD) sizeof (buf)); + return ((rc != 0) && (rc < sizeof (buf))) ? buf : NULL; + #else /* we might need other platforms, or a simple `return NULL;` for platforms without an environment table. */ + return getenv(name); #endif } -/* this talks right to the OS environment table. Don't use SDL20_setenv at startup. */ -static void SDL12COMPAT_SetEnvAtStartup(const char *name, const char *value) +static void SDL12COMPAT_setenv_unsafe(const char *name, const char *value) { #ifdef _WIN32 SetEnvironmentVariableA(name, value); @@ -1211,15 +1209,27 @@ static void SDL12COMPAT_SetEnvAtStartup(const char *name, const char *value) #endif } -/* this talks right to the OS environment table. Don't use SDL20_getenv at startup. */ static const char *SDL12COMPAT_GetEnvAtStartup(const char *name) +{ + return SDL12COMPAT_getenv_unsafe(name); /* don't talk to SDL2 yet, we aren't set up. Go right to the OS interfaces. */ +} + +static void SDL12COMPAT_SetEnvAtStartup(const char *name, const char *value) +{ + SDL12COMPAT_setenv_unsafe(name, value); /* don't talk to SDL2 yet, we aren't set up. Go right to the OS interfaces. */ +} + +/* log a string using platform-specific code for before SDL2 is fully available. */ +static void SDL12COMPAT_LogAtStartup(const char *str) { #ifdef _WIN32 - static char buf[256]; /* overflows will just report as environment variable being unset. But most of our environment vars don't come through here. */ - const DWORD rc = GetEnvironmentVariableA(name, buf, (DWORD) sizeof (buf)); - return ((rc != 0) && (rc < sizeof (buf))) ? buf : NULL; - #else /* we might need other platforms, or a simple `return NULL;` for platforms without an environment table. */ - return getenv(name); + OutputDebugStringA(str); + #elif defined(__APPLE__) + extern void SDL12COMPAT_NSLog(const char *prefix, const char *text); + SDL12COMPAT_NSLog(NULL, str); + #else + fputs(str, stderr); + fputs("\n", stderr); #endif } @@ -1310,7 +1320,7 @@ static char loaderror[256]; homedir = pwent->pw_dir; } if (!homedir) { - homedir = getenv("HOME"); + homedir = SDL12COMPAT_getenv_unsafe("HOME"); } if (homedir) { char framework[512]; @@ -1531,7 +1541,7 @@ SDL12Compat_GetExeName(void) static const char * SDL12Compat_GetHint(const char *name) { - return SDL20_getenv(name); + return SDL12COMPAT_getenv_unsafe(name); } static SDL_bool @@ -2395,9 +2405,9 @@ static int GetVideoDisplay(void) { const char *variable; - variable = SDL20_getenv("SDL_VIDEO_FULLSCREEN_DISPLAY"); + variable = SDL12COMPAT_getenv_unsafe("SDL_VIDEO_FULLSCREEN_DISPLAY"); if (!variable) { - variable = SDL20_getenv("SDL_VIDEO_FULLSCREEN_HEAD"); + variable = SDL12COMPAT_getenv_unsafe("SDL_VIDEO_FULLSCREEN_HEAD"); } if (variable) { int preferred_display = SDL20_atoi(variable); @@ -2780,23 +2790,16 @@ static void QuitCDSubsystem(void); DECLSPEC12 int SDLCALL SDL_InitSubSystem(Uint32 sdl12flags) { + const char *videodriver = SDL12COMPAT_getenv_unsafe("SDL_VIDEODRIVER"); + const char *audiodriver = SDL12COMPAT_getenv_unsafe("SDL_AUDIODRIVER"); Uint32 sdl20flags = 0; int rc; #ifdef __WINDOWS__ /* DOSBox (and probably other things), try to force the "windib" video backend, but it doesn't exist in SDL2. Force to "windows" instead. */ - const char *origvidenv = NULL; - const char *env = SDL20_getenv("SDL_VIDEODRIVER"); - if (env) { - if (SDL20_strcmp(env, "windib") == 0) { - origvidenv = "windib"; - SDL20_setenv("SDL_VIDEODRIVER", "windows", 1); - } else - if (SDL20_strcmp(env, "directx") == 0) { - origvidenv = "directx"; - SDL20_setenv("SDL_VIDEODRIVER", "windows", 1); - } + if (videodriver && (SDL20_strcmp(videodriver, "windib") == 0) || (SDL20_strcmp(videodriver, "directx") == 0)) { + videodriver = "windows"; } #endif @@ -2835,6 +2838,17 @@ SDL_InitSubSystem(Uint32 sdl12flags) InitializeCDSubsystem(); } + /* In SDL3 (via sdl2-compat), these will ignore changes to environment variables after startup, but SDL-1.2 apps might + change envvars on the fly, so we need to manually force these into SDL2 hints. */ + + if (videodriver) { + SDL20_SetHintWithPriority(SDL_HINT_VIDEODRIVER, videodriver, SDL_HINT_OVERRIDE); + } + + if (audiodriver) { + SDL20_SetHintWithPriority(SDL_HINT_AUDIODRIVER, audiodriver, SDL_HINT_OVERRIDE); + } + rc = SDL20_Init(sdl20flags); if ((rc == 0) && (sdl20flags & SDL_INIT_VIDEO)) { if (Init12Video() < 0) { @@ -2845,12 +2859,6 @@ SDL_InitSubSystem(Uint32 sdl12flags) EventThreadEnabled = (sdl12flags & SDL12_INIT_EVENTTHREAD) ? SDL_TRUE : SDL_FALSE; } -#ifdef __WINDOWS__ - if (origvidenv) { /* set this back to minimize surprise state changes. */ - SDL20_setenv("SDL_VIDEODRIVER", origvidenv, 1); - } -#endif - if ((rc == 0) && (sdl20flags & SDL_INIT_AUDIO)) { Init12Audio(); } @@ -3086,7 +3094,7 @@ DECLSPEC12 const char * SDLCALL SDL_VideoDriverName(char *namebuf, int maxlen) { #ifdef __WINDOWS__ - const char *val = SDL20_getenv("SDL_VIDEODRIVER"); + const char *val = SDL12COMPAT_getenv_unsafe("SDL_VIDEODRIVER"); if (val) { /* give them back what they requested: */ if (SDL20_strcmp(val, "windib") == 0 || @@ -5949,8 +5957,8 @@ static void GetEnvironmentWindowPosition(int *x, int *y) { int display = VideoDisplayIndex; - const char *window = SDL20_getenv("SDL_VIDEO_WINDOW_POS"); - const char *center = SDL20_getenv("SDL_VIDEO_CENTERED"); + const char *window = SDL12COMPAT_getenv_unsafe("SDL_VIDEO_WINDOW_POS"); + const char *center = SDL12COMPAT_getenv_unsafe("SDL_VIDEO_CENTERED"); if (window) { if (SDL20_strcmp(window, "center") == 0) { center = window; @@ -6576,7 +6584,7 @@ SetVideoModeImpl(int width, int height, int bpp, Uint32 flags12) fullscreen_flags20 |= SDL_WINDOW_FULLSCREEN_DESKTOP; } - fromwin_env = SDL20_getenv("SDL_WINDOWID"); + fromwin_env = SDL12COMPAT_getenv_unsafe("SDL_WINDOWID"); if (fromwin_env) { window_size_scaling = 1.0f; /* don't scale for external windows */ @@ -8599,6 +8607,11 @@ SDL_Delay(Uint32 ticks) SDL20_Delay(ticks); } +DECLSPEC12 char * SDLCALL +SDL_getenv(const char *name) +{ + return SDL12COMPAT_getenv_unsafe(name); +} DECLSPEC12 int SDLCALL SDL_putenv(const char *_var) @@ -8616,7 +8629,7 @@ SDL_putenv(const char *_var) } *ptr = '\0'; /* split the string into name and value. */ - SDL20_setenv(var, ptr + 1, 1); + SDL12COMPAT_setenv_unsafe(var, ptr + 1); SDL20_free(var); return 0; } @@ -9999,7 +10012,7 @@ SDL_OpenAudio(SDL_AudioSpec *want, SDL_AudioSpec *obtained) } if (!want->format) { - const char *env = SDL20_getenv("SDL_AUDIO_FORMAT"); /* SDL 1.2 checks this. */ + const char *env = SDL12COMPAT_getenv_unsafe("SDL_AUDIO_FORMAT"); /* SDL 1.2 checks this. */ if (env != NULL) { if (SDL20_strcmp(env, "U8") == 0) { want->format = AUDIO_U8; } else if (SDL20_strcmp(env, "S8") == 0) { want->format = AUDIO_S8; } @@ -10018,7 +10031,7 @@ SDL_OpenAudio(SDL_AudioSpec *want, SDL_AudioSpec *obtained) } if (!want->freq) { - const char *env = SDL20_getenv("SDL_AUDIO_FREQUENCY"); /* SDL 1.2 checks this. */ + const char *env = SDL12COMPAT_getenv_unsafe("SDL_AUDIO_FREQUENCY"); /* SDL 1.2 checks this. */ if (env != NULL) { want->freq = SDL20_atoi(env); } @@ -10029,7 +10042,7 @@ SDL_OpenAudio(SDL_AudioSpec *want, SDL_AudioSpec *obtained) } if (!want->channels) { - const char *env = SDL20_getenv("SDL_AUDIO_CHANNELS"); /* SDL 1.2 checks this. */ + const char *env = SDL12COMPAT_getenv_unsafe("SDL_AUDIO_CHANNELS"); /* SDL 1.2 checks this. */ if (env != NULL) { want->channels = SDL20_atoi(env); } @@ -10039,7 +10052,7 @@ SDL_OpenAudio(SDL_AudioSpec *want, SDL_AudioSpec *obtained) } if (!want->samples) { - const char *env = SDL20_getenv("SDL_AUDIO_SAMPLES"); /* SDL 1.2 checks this. */ + const char *env = SDL12COMPAT_getenv_unsafe("SDL_AUDIO_SAMPLES"); /* SDL 1.2 checks this. */ if (env != NULL) { want->samples = SDL20_atoi(env); } diff --git a/src/SDL20_syms.h b/src/SDL20_syms.h index ab7572d1b..5f1a2c9cb 100644 --- a/src/SDL20_syms.h +++ b/src/SDL20_syms.h @@ -273,7 +273,6 @@ SDL20_SYM_PASSTHROUGH(void *,malloc,(size_t a),(a),return) SDL20_SYM_PASSTHROUGH(void *,calloc,(size_t a, size_t b),(a,b),return) SDL20_SYM_PASSTHROUGH(void *,realloc,(void *a, size_t b),(a,b),return) SDL20_SYM_PASSTHROUGH(void,free,(void *a),(a),) -SDL20_SYM_PASSTHROUGH(char *,getenv,(const char *a),(a),return) SDL20_SYM_PASSTHROUGH(void,qsort,(void *a, size_t b, size_t c, int (SDLCALL *d)(const void *, const void *)),(a,b,c,d),) SDL20_SYM_PASSTHROUGH(void *,memset,(void *a, int b, size_t c),(a,b,c),return) SDL20_SYM_PASSTHROUGH(void *,memcpy,(void *a, const void *b, size_t c),(a,b,c),return) @@ -337,6 +336,8 @@ SDL20_SYM(void,DestroyTexture,(SDL_Texture *a),(a),) SDL20_SYM(void,DestroyRenderer,(SDL_Renderer *a),(a),) SDL20_SYM(void,RenderPresent,(SDL_Renderer *a),(a),) +SDL20_SYM(SDL_bool,SetHintWithPriority,(const char *a, const char *b, SDL_HintPriority c),(a,b,c),return) + #ifdef _WIN32 SDL20_SYM_PASSTHROUGH(int,RegisterApp,(const char *a, Uint32 b, void *c),(a,b,c),return) SDL20_SYM_PASSTHROUGH(void,UnregisterApp,(void),(),) From bef8f7412dd44edc4f7e14dc35d3b20399e25496 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 6 Nov 2025 07:19:20 -0800 Subject: [PATCH 577/606] Revert "Don't include glu.h by default" This reverts commit 6595f6e405844cbca4a55e47eaa29ccec0cdd75f. It turns out there are a number of games that depend on this: * antigrav * armagetronad * bloboats * blockout2 * brutalchess * cytadela * enemylines3 * enemylines7 * opencity * pathogen Fixes https://github.com/libsdl-org/sdl12-compat/issues/382 --- include/SDL/SDL_opengl.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/include/SDL/SDL_opengl.h b/include/SDL/SDL_opengl.h index ba92b114f..776541a20 100644 --- a/include/SDL/SDL_opengl.h +++ b/include/SDL/SDL_opengl.h @@ -45,15 +45,11 @@ real SDL-1.2 available to you. */ #endif #if defined(__MACOSX__) #include /* Header File For The OpenGL Library */ -#ifdef SDL_INCLUDE_GLU_H #include /* Header File For The GLU Library */ -#endif #else #include /* Header File For The OpenGL Library */ -#ifdef SDL_INCLUDE_GLU_H #include /* Header File For The GLU Library */ #endif -#endif #ifndef NO_SDL_GLEXT #undef __glext_h_ #undef __gl_glext_h_ From 45fb7be084c477b5d6b0df53f3e93200abd51f40 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 7 Nov 2025 11:04:27 -0800 Subject: [PATCH 578/606] Allow building without glu.h by defining NO_SDL_GLU Reference: https://github.com/libsdl-org/sdl12-compat/issues/358 --- include/SDL/SDL_opengl.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/SDL/SDL_opengl.h b/include/SDL/SDL_opengl.h index 776541a20..8447fbf10 100644 --- a/include/SDL/SDL_opengl.h +++ b/include/SDL/SDL_opengl.h @@ -45,11 +45,15 @@ real SDL-1.2 available to you. */ #endif #if defined(__MACOSX__) #include /* Header File For The OpenGL Library */ +#ifndef NO_SDL_GLU #include /* Header File For The GLU Library */ +#endif #else #include /* Header File For The OpenGL Library */ +#ifndef NO_SDL_GLU #include /* Header File For The GLU Library */ #endif +#endif #ifndef NO_SDL_GLEXT #undef __glext_h_ #undef __gl_glext_h_ From 4f7a4386930ca8aa2ae8a9073480226665d27bff Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sun, 30 Nov 2025 00:05:24 +0300 Subject: [PATCH 579/606] update to latest dr_mp3.h from mainstream --- src/dr_mp3.h | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/src/dr_mp3.h b/src/dr_mp3.h index 93e02b5c9..fe81e0814 100644 --- a/src/dr_mp3.h +++ b/src/dr_mp3.h @@ -3036,23 +3036,27 @@ static drmp3_bool32 drmp3_init_internal(drmp3* pMP3, drmp3_read_proc onRead, drm ((drmp3_uint32)ape[26] << 16) | ((drmp3_uint32)ape[27] << 24); - streamEndOffset -= 32 + tagSize; - streamLen -= 32 + tagSize; - - /* Fire a metadata callback for the APE data. Must include both the main content and footer. */ - if (onMeta != NULL) { - /* We first need to seek to the start of the APE tag. */ - if (onSeek(pUserData, streamEndOffset, DRMP3_SEEK_END)) { - size_t apeTagSize = (size_t)tagSize + 32; - drmp3_uint8* pTagData = (drmp3_uint8*)drmp3_malloc(apeTagSize, pAllocationCallbacks); - if (pTagData != NULL) { - if (onRead(pUserData, pTagData, apeTagSize) == apeTagSize) { - drmp3__on_meta(pMP3, DRMP3_METADATA_TYPE_APE, pTagData, apeTagSize); + if (32 + tagSize < streamLen) { + streamEndOffset -= 32 + tagSize; + streamLen -= 32 + tagSize; + + /* Fire a metadata callback for the APE data. Must include both the main content and footer. */ + if (onMeta != NULL) { + /* We first need to seek to the start of the APE tag. */ + if (onSeek(pUserData, streamEndOffset, DRMP3_SEEK_END)) { + size_t apeTagSize = (size_t)tagSize + 32; + drmp3_uint8* pTagData = (drmp3_uint8*)drmp3_malloc(apeTagSize, pAllocationCallbacks); + if (pTagData != NULL) { + if (onRead(pUserData, pTagData, apeTagSize) == apeTagSize) { + drmp3__on_meta(pMP3, DRMP3_METADATA_TYPE_APE, pTagData, apeTagSize); + } + + drmp3_free(pTagData, pAllocationCallbacks); } - - drmp3_free(pTagData, pAllocationCallbacks); } } + } else { + /* The tag size is larger than the stream. Invalid APE tag. */ } } } @@ -5031,6 +5035,7 @@ REVISION HISTORY v0.7.2 - TBD - Reduce stack space to improve robustness on embedded systems. - Fix a compilation error with MSVC Clang toolset relating to cpuid. + - Fix an error with APE tag parsing. v0.7.1 - 2025-09-10 - Silence a warning with GCC. From 9eedb893fdf0bb209ca1b26a3e38739595650bee Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 2 Dec 2025 11:41:16 -0800 Subject: [PATCH 580/606] Updated to version 1.2.72 for release --- CMakeLists.txt | 4 ++-- include/SDL/SDL_version.h | 2 +- src/Makefile.darwin | 2 +- src/Makefile.linux | 2 +- src/Makefile.os2 | 2 +- src/Makefile.w32 | 2 +- src/SDL12_compat.c | 2 +- src/version.rc | 8 ++++---- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f4c83332e..a932c6d82 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ # cmake -DSDL2_INCLUDE_DIR=/opt/SDL2/include/SDL2 [other stuff] cmake_minimum_required(VERSION 3.0.0...4.1) -project(sdl12_compat VERSION 1.2.71 LANGUAGES C) +project(sdl12_compat VERSION 1.2.72 LANGUAGES C) option(SDL12TESTS "Enable to build SDL-1.2 test programs" ON) option(SDL12DEVEL "Enable installing SDL-1.2 development headers" ON) @@ -33,7 +33,7 @@ if(APPLE) # Xcode project file uses 1.0.0, but it's more compatible to use the # higher version. set(DYLIB_COMPAT_VERSION 12.0.0 CACHE STRING "library compatibility version") - set(DYLIB_CURRENT_VERSION 12.71.0 CACHE STRING "library current version") + set(DYLIB_CURRENT_VERSION 12.72.0 CACHE STRING "library current version") include_directories("/opt/X11/include") # hack. if(CMAKE_VERSION VERSION_LESS 3.9) else() diff --git a/include/SDL/SDL_version.h b/include/SDL/SDL_version.h index 2f9a4d132..09b966227 100644 --- a/include/SDL/SDL_version.h +++ b/include/SDL/SDL_version.h @@ -33,7 +33,7 @@ real SDL-1.2 available to you. */ /* We bumped the patchlevel to 50 for sdl12-compat */ #define SDL_MAJOR_VERSION 1 #define SDL_MINOR_VERSION 2 -#define SDL_PATCHLEVEL 71 +#define SDL_PATCHLEVEL 72 typedef struct SDL_version { diff --git a/src/Makefile.darwin b/src/Makefile.darwin index 73cc50919..d61759647 100644 --- a/src/Makefile.darwin +++ b/src/Makefile.darwin @@ -18,7 +18,7 @@ CFLAGS = -mmacosx-version-min=10.6 -fPIC -O3 -Wall LDFLAGS = -mmacosx-version-min=10.6 -dynamiclib -Wl,-undefined,error -Wl,-single_module #LDFLAGS+= -Wl,-headerpad_max_install_names LDFLAGS+= -Wl,-install_name,"/usr/local/lib/$(DYLIB)" -LDFLAGS+= -Wl,-compatibility_version,1.0 -Wl,-current_version,12.71 +LDFLAGS+= -Wl,-compatibility_version,1.0 -Wl,-current_version,12.72 LDLIBS = -Wl,-framework,AppKit # this is needed for x86_64 - cross-gcc might not add it. #LDLIBS += -Wl,-lbundle1.o diff --git a/src/Makefile.linux b/src/Makefile.linux index 483ad2e18..c9ecfd22a 100644 --- a/src/Makefile.linux +++ b/src/Makefile.linux @@ -16,7 +16,7 @@ LDFLAGS = -shared -Wl,-soname,libSDL-1.2.so.0 LDFLAGS+= -Wl,--no-undefined LDLIBS = -ldl -SHLIB = libSDL-1.2.so.1.2.71 +SHLIB = libSDL-1.2.so.1.2.72 OBJ = SDL12_compat.o diff --git a/src/Makefile.os2 b/src/Makefile.os2 index c948f5ae7..e560aba15 100644 --- a/src/Makefile.os2 +++ b/src/Makefile.os2 @@ -5,7 +5,7 @@ !endif DLLNAME = SDL12 -VERSION = 1.2.71 +VERSION = 1.2.72 # change SDL2INC to point to the SDL2 headers SDL2INC = include diff --git a/src/Makefile.w32 b/src/Makefile.w32 index 16054bdc4..c2d8b3121 100644 --- a/src/Makefile.w32 +++ b/src/Makefile.w32 @@ -5,7 +5,7 @@ !endif DLLNAME = SDL -VERSION = 1.2.71 +VERSION = 1.2.72 # change SDL2INC to point to the SDL2 headers SDL2INC = include diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index fab38d40b..0c331a36d 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -28,7 +28,7 @@ * should be way ahead of what SDL-1.2 Classic would report, so apps can * decide if they're running under the compat layer, if they really care. */ -#define SDL12_COMPAT_VERSION 71 +#define SDL12_COMPAT_VERSION 72 #include #include diff --git a/src/version.rc b/src/version.rc index 7e4d60383..3276be156 100644 --- a/src/version.rc +++ b/src/version.rc @@ -3,8 +3,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,2,71,0 - PRODUCTVERSION 1,2,71,0 + FILEVERSION 1,2,72,0 + PRODUCTVERSION 1,2,72,0 FILEFLAGSMASK 0x3fL FILEFLAGS 0x0L FILEOS 0x40004L @@ -17,12 +17,12 @@ BEGIN BEGIN VALUE "CompanyName", "\0" VALUE "FileDescription", "SDL\0" - VALUE "FileVersion", "1, 2, 71, 0\0" + VALUE "FileVersion", "1, 2, 72, 0\0" VALUE "InternalName", "SDL\0" VALUE "LegalCopyright", "Copyright (C) 2025 Sam Lantinga\0" VALUE "OriginalFilename", "SDL.dll\0" VALUE "ProductName", "Simple DirectMedia Layer 1.2 wrapper\0" - VALUE "ProductVersion", "1, 2, 71, 0\0" + VALUE "ProductVersion", "1, 2, 72, 0\0" END END BLOCK "VarFileInfo" From 49be0d7522a49dd76b7c51864b4fbfcab2fc67ea Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 2 Dec 2025 12:09:18 -0800 Subject: [PATCH 581/606] Install GLU development headers for the linux-verify step --- .github/workflows/release.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 14e1d239c..c3d86d6fc 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -110,6 +110,10 @@ jobs: install-linux-dependencies: true - name: Set up ninja uses: ./.github/actions/setup-ninja + - name: Install GLU development headers + run: | + sudo apt update -q + sudo apt install -y libgl1-mesa-dev libglu1-mesa-dev - name: 'CMake (configure + build)' run: | cmake \ From fc2ec0c128197f1f5050e48359bc41e618f3abfb Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 2 Dec 2025 12:13:41 -0800 Subject: [PATCH 582/606] libgl1-mesa-dev is already installed --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c3d86d6fc..9841ee9e2 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -113,7 +113,7 @@ jobs: - name: Install GLU development headers run: | sudo apt update -q - sudo apt install -y libgl1-mesa-dev libglu1-mesa-dev + sudo apt install -y libglu1-mesa-dev - name: 'CMake (configure + build)' run: | cmake \ From a26094d2bc437cb45055f6a474f95779c7181bca Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 2 Dec 2025 14:48:10 -0800 Subject: [PATCH 583/606] Updated to version 1.2.73 for development --- CMakeLists.txt | 4 ++-- include/SDL/SDL_version.h | 2 +- src/Makefile.darwin | 2 +- src/Makefile.linux | 2 +- src/Makefile.os2 | 2 +- src/Makefile.w32 | 2 +- src/SDL12_compat.c | 2 +- src/version.rc | 8 ++++---- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a932c6d82..628a0f364 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ # cmake -DSDL2_INCLUDE_DIR=/opt/SDL2/include/SDL2 [other stuff] cmake_minimum_required(VERSION 3.0.0...4.1) -project(sdl12_compat VERSION 1.2.72 LANGUAGES C) +project(sdl12_compat VERSION 1.2.73 LANGUAGES C) option(SDL12TESTS "Enable to build SDL-1.2 test programs" ON) option(SDL12DEVEL "Enable installing SDL-1.2 development headers" ON) @@ -33,7 +33,7 @@ if(APPLE) # Xcode project file uses 1.0.0, but it's more compatible to use the # higher version. set(DYLIB_COMPAT_VERSION 12.0.0 CACHE STRING "library compatibility version") - set(DYLIB_CURRENT_VERSION 12.72.0 CACHE STRING "library current version") + set(DYLIB_CURRENT_VERSION 12.73.0 CACHE STRING "library current version") include_directories("/opt/X11/include") # hack. if(CMAKE_VERSION VERSION_LESS 3.9) else() diff --git a/include/SDL/SDL_version.h b/include/SDL/SDL_version.h index 09b966227..3c948bc68 100644 --- a/include/SDL/SDL_version.h +++ b/include/SDL/SDL_version.h @@ -33,7 +33,7 @@ real SDL-1.2 available to you. */ /* We bumped the patchlevel to 50 for sdl12-compat */ #define SDL_MAJOR_VERSION 1 #define SDL_MINOR_VERSION 2 -#define SDL_PATCHLEVEL 72 +#define SDL_PATCHLEVEL 73 typedef struct SDL_version { diff --git a/src/Makefile.darwin b/src/Makefile.darwin index d61759647..ded709ad6 100644 --- a/src/Makefile.darwin +++ b/src/Makefile.darwin @@ -18,7 +18,7 @@ CFLAGS = -mmacosx-version-min=10.6 -fPIC -O3 -Wall LDFLAGS = -mmacosx-version-min=10.6 -dynamiclib -Wl,-undefined,error -Wl,-single_module #LDFLAGS+= -Wl,-headerpad_max_install_names LDFLAGS+= -Wl,-install_name,"/usr/local/lib/$(DYLIB)" -LDFLAGS+= -Wl,-compatibility_version,1.0 -Wl,-current_version,12.72 +LDFLAGS+= -Wl,-compatibility_version,1.0 -Wl,-current_version,12.73 LDLIBS = -Wl,-framework,AppKit # this is needed for x86_64 - cross-gcc might not add it. #LDLIBS += -Wl,-lbundle1.o diff --git a/src/Makefile.linux b/src/Makefile.linux index c9ecfd22a..70c152047 100644 --- a/src/Makefile.linux +++ b/src/Makefile.linux @@ -16,7 +16,7 @@ LDFLAGS = -shared -Wl,-soname,libSDL-1.2.so.0 LDFLAGS+= -Wl,--no-undefined LDLIBS = -ldl -SHLIB = libSDL-1.2.so.1.2.72 +SHLIB = libSDL-1.2.so.1.2.73 OBJ = SDL12_compat.o diff --git a/src/Makefile.os2 b/src/Makefile.os2 index e560aba15..ac17dfa99 100644 --- a/src/Makefile.os2 +++ b/src/Makefile.os2 @@ -5,7 +5,7 @@ !endif DLLNAME = SDL12 -VERSION = 1.2.72 +VERSION = 1.2.73 # change SDL2INC to point to the SDL2 headers SDL2INC = include diff --git a/src/Makefile.w32 b/src/Makefile.w32 index c2d8b3121..455f71796 100644 --- a/src/Makefile.w32 +++ b/src/Makefile.w32 @@ -5,7 +5,7 @@ !endif DLLNAME = SDL -VERSION = 1.2.72 +VERSION = 1.2.73 # change SDL2INC to point to the SDL2 headers SDL2INC = include diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 0c331a36d..72af0fb46 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -28,7 +28,7 @@ * should be way ahead of what SDL-1.2 Classic would report, so apps can * decide if they're running under the compat layer, if they really care. */ -#define SDL12_COMPAT_VERSION 72 +#define SDL12_COMPAT_VERSION 73 #include #include diff --git a/src/version.rc b/src/version.rc index 3276be156..7a42fb868 100644 --- a/src/version.rc +++ b/src/version.rc @@ -3,8 +3,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,2,72,0 - PRODUCTVERSION 1,2,72,0 + FILEVERSION 1,2,73,0 + PRODUCTVERSION 1,2,73,0 FILEFLAGSMASK 0x3fL FILEFLAGS 0x0L FILEOS 0x40004L @@ -17,12 +17,12 @@ BEGIN BEGIN VALUE "CompanyName", "\0" VALUE "FileDescription", "SDL\0" - VALUE "FileVersion", "1, 2, 72, 0\0" + VALUE "FileVersion", "1, 2, 73, 0\0" VALUE "InternalName", "SDL\0" VALUE "LegalCopyright", "Copyright (C) 2025 Sam Lantinga\0" VALUE "OriginalFilename", "SDL.dll\0" VALUE "ProductName", "Simple DirectMedia Layer 1.2 wrapper\0" - VALUE "ProductVersion", "1, 2, 72, 0\0" + VALUE "ProductVersion", "1, 2, 73, 0\0" END END BLOCK "VarFileInfo" From 2eea59a1e9a133ffad3dfa1fe194b7cf0547819a Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Tue, 16 Dec 2025 20:33:10 +0300 Subject: [PATCH 584/606] updated dr_mp3.h from mainstream. --- src/dr_mp3.h | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/dr_mp3.h b/src/dr_mp3.h index fe81e0814..a253c2298 100644 --- a/src/dr_mp3.h +++ b/src/dr_mp3.h @@ -1,6 +1,6 @@ /* MP3 audio decoder. Choice of public domain or MIT-0. See license statements at the end of this file. -dr_mp3 - v0.7.2 - TBD +dr_mp3 - v0.7.3 - TBD David Reid - mackron@gmail.com @@ -78,7 +78,7 @@ extern "C" { #define DRMP3_VERSION_MAJOR 0 #define DRMP3_VERSION_MINOR 7 -#define DRMP3_VERSION_REVISION 2 +#define DRMP3_VERSION_REVISION 3 #define DRMP3_VERSION_STRING DRMP3_XSTRINGIFY(DRMP3_VERSION_MAJOR) "." DRMP3_XSTRINGIFY(DRMP3_VERSION_MINOR) "." DRMP3_XSTRINGIFY(DRMP3_VERSION_REVISION) #include /* For size_t. */ @@ -4825,6 +4825,8 @@ static float* drmp3__full_read_and_close_f32(drmp3* pMP3, drmp3_config* pConfig, pNewFrames = (float*)drmp3__realloc_from_callbacks(pFrames, (size_t)newFramesBufferSize, (size_t)oldFramesBufferSize, &pMP3->allocationCallbacks); if (pNewFrames == NULL) { drmp3__free_from_callbacks(pFrames, &pMP3->allocationCallbacks); + pFrames = NULL; + totalFramesRead = 0; break; } @@ -4893,6 +4895,8 @@ static drmp3_int16* drmp3__full_read_and_close_s16(drmp3* pMP3, drmp3_config* pC pNewFrames = (drmp3_int16*)drmp3__realloc_from_callbacks(pFrames, (size_t)newFramesBufferSize, (size_t)oldFramesBufferSize, &pMP3->allocationCallbacks); if (pNewFrames == NULL) { drmp3__free_from_callbacks(pFrames, &pMP3->allocationCallbacks); + pFrames = NULL; + totalFramesRead = 0; break; } @@ -5032,7 +5036,10 @@ DIFFERENCES BETWEEN minimp3 AND dr_mp3 /* REVISION HISTORY ================ -v0.7.2 - TBD +v0.7.3 - TBD + - Fix an error in drmp3_open_and_read_pcm_frames_s16() and family when memory allocation fails. + +v0.7.2 - 2025-12-02 - Reduce stack space to improve robustness on embedded systems. - Fix a compilation error with MSVC Clang toolset relating to cpuid. - Fix an error with APE tag parsing. From 9038bdc9d383272dcfe824412cdb7bb6defe1939 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 1 Jan 2026 10:02:30 -0800 Subject: [PATCH 585/606] Updated copyright for 2026 --- LICENSE.txt | 2 +- include/SDL/SDL.h | 2 +- include/SDL/SDL_active.h | 2 +- include/SDL/SDL_audio.h | 2 +- include/SDL/SDL_byteorder.h | 2 +- include/SDL/SDL_cdrom.h | 2 +- include/SDL/SDL_config.h | 2 +- include/SDL/SDL_copying.h | 2 +- include/SDL/SDL_cpuinfo.h | 2 +- include/SDL/SDL_endian.h | 2 +- include/SDL/SDL_error.h | 2 +- include/SDL/SDL_events.h | 2 +- include/SDL/SDL_getenv.h | 2 +- include/SDL/SDL_joystick.h | 2 +- include/SDL/SDL_keyboard.h | 2 +- include/SDL/SDL_keysym.h | 2 +- include/SDL/SDL_loadso.h | 2 +- include/SDL/SDL_main.h | 2 +- include/SDL/SDL_mouse.h | 2 +- include/SDL/SDL_mutex.h | 2 +- include/SDL/SDL_name.h | 2 +- include/SDL/SDL_opengl.h | 2 +- include/SDL/SDL_platform.h | 2 +- include/SDL/SDL_quit.h | 2 +- include/SDL/SDL_rwops.h | 2 +- include/SDL/SDL_stdinc.h | 2 +- include/SDL/SDL_syswm.h | 2 +- include/SDL/SDL_thread.h | 2 +- include/SDL/SDL_timer.h | 2 +- include/SDL/SDL_types.h | 2 +- include/SDL/SDL_version.h | 2 +- include/SDL/SDL_video.h | 2 +- include/SDL/begin_code.h | 2 +- include/SDL/close_code.h | 2 +- src/SDL12_compat.c | 2 +- src/SDL12_compat_objc.m | 2 +- src/SDL20_include_wrapper.h | 2 +- src/SDL20_syms.h | 2 +- src/default_cursor.h | 2 +- src/version.rc | 2 +- src/x86_msvc.h | 2 +- 41 files changed, 41 insertions(+), 41 deletions(-) diff --git a/LICENSE.txt b/LICENSE.txt index b9d0beff3..6a085d050 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,4 +1,4 @@ -Copyright (C) 1997-2025 Sam Lantinga +Copyright (C) 1997-2026 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL.h b/include/SDL/SDL.h index b94b832e1..02da2ff44 100644 --- a/include/SDL/SDL.h +++ b/include/SDL/SDL.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga + Copyright (C) 1997-2026 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_active.h b/include/SDL/SDL_active.h index 3d139c349..b344827e6 100644 --- a/include/SDL/SDL_active.h +++ b/include/SDL/SDL_active.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga + Copyright (C) 1997-2026 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_audio.h b/include/SDL/SDL_audio.h index a9972e84b..05987bf5b 100644 --- a/include/SDL/SDL_audio.h +++ b/include/SDL/SDL_audio.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga + Copyright (C) 1997-2026 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_byteorder.h b/include/SDL/SDL_byteorder.h index 1c78c4464..5b9ad06e0 100644 --- a/include/SDL/SDL_byteorder.h +++ b/include/SDL/SDL_byteorder.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga + Copyright (C) 1997-2026 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_cdrom.h b/include/SDL/SDL_cdrom.h index acd4f7e3f..62ad330b9 100644 --- a/include/SDL/SDL_cdrom.h +++ b/include/SDL/SDL_cdrom.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga + Copyright (C) 1997-2026 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_config.h b/include/SDL/SDL_config.h index ac191c19a..f8185219b 100644 --- a/include/SDL/SDL_config.h +++ b/include/SDL/SDL_config.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga + Copyright (C) 1997-2026 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_copying.h b/include/SDL/SDL_copying.h index d0bc88f07..4695197db 100644 --- a/include/SDL/SDL_copying.h +++ b/include/SDL/SDL_copying.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga + Copyright (C) 1997-2026 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_cpuinfo.h b/include/SDL/SDL_cpuinfo.h index adc0b3a6c..8e3fd4387 100644 --- a/include/SDL/SDL_cpuinfo.h +++ b/include/SDL/SDL_cpuinfo.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga + Copyright (C) 1997-2026 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_endian.h b/include/SDL/SDL_endian.h index a44c40b1a..bfd0b8cf8 100644 --- a/include/SDL/SDL_endian.h +++ b/include/SDL/SDL_endian.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga + Copyright (C) 1997-2026 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_error.h b/include/SDL/SDL_error.h index ee13381c3..2f0b5de02 100644 --- a/include/SDL/SDL_error.h +++ b/include/SDL/SDL_error.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga + Copyright (C) 1997-2026 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_events.h b/include/SDL/SDL_events.h index 64774baa6..18e4c770a 100644 --- a/include/SDL/SDL_events.h +++ b/include/SDL/SDL_events.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga + Copyright (C) 1997-2026 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_getenv.h b/include/SDL/SDL_getenv.h index 3db709c2a..885ff883c 100644 --- a/include/SDL/SDL_getenv.h +++ b/include/SDL/SDL_getenv.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga + Copyright (C) 1997-2026 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_joystick.h b/include/SDL/SDL_joystick.h index d51793481..6c63f843a 100644 --- a/include/SDL/SDL_joystick.h +++ b/include/SDL/SDL_joystick.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga + Copyright (C) 1997-2026 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_keyboard.h b/include/SDL/SDL_keyboard.h index 7f68d6b4c..1e091da34 100644 --- a/include/SDL/SDL_keyboard.h +++ b/include/SDL/SDL_keyboard.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga + Copyright (C) 1997-2026 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_keysym.h b/include/SDL/SDL_keysym.h index 053ae4351..cfc98867b 100644 --- a/include/SDL/SDL_keysym.h +++ b/include/SDL/SDL_keysym.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga + Copyright (C) 1997-2026 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_loadso.h b/include/SDL/SDL_loadso.h index 5b01a9463..22f05718e 100644 --- a/include/SDL/SDL_loadso.h +++ b/include/SDL/SDL_loadso.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga + Copyright (C) 1997-2026 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_main.h b/include/SDL/SDL_main.h index 4c347266a..7513b2844 100644 --- a/include/SDL/SDL_main.h +++ b/include/SDL/SDL_main.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga + Copyright (C) 1997-2026 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_mouse.h b/include/SDL/SDL_mouse.h index 36d762385..8006b7b00 100644 --- a/include/SDL/SDL_mouse.h +++ b/include/SDL/SDL_mouse.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga + Copyright (C) 1997-2026 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_mutex.h b/include/SDL/SDL_mutex.h index 25a1b3f39..8d09eefd1 100644 --- a/include/SDL/SDL_mutex.h +++ b/include/SDL/SDL_mutex.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga + Copyright (C) 1997-2026 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_name.h b/include/SDL/SDL_name.h index 635c288a0..52c8a5a86 100644 --- a/include/SDL/SDL_name.h +++ b/include/SDL/SDL_name.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga + Copyright (C) 1997-2026 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_opengl.h b/include/SDL/SDL_opengl.h index 8447fbf10..81dd20826 100644 --- a/include/SDL/SDL_opengl.h +++ b/include/SDL/SDL_opengl.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga + Copyright (C) 1997-2026 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_platform.h b/include/SDL/SDL_platform.h index 72f7dc9b6..1933e299b 100644 --- a/include/SDL/SDL_platform.h +++ b/include/SDL/SDL_platform.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga + Copyright (C) 1997-2026 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_quit.h b/include/SDL/SDL_quit.h index 505a01003..c1c8a7ab8 100644 --- a/include/SDL/SDL_quit.h +++ b/include/SDL/SDL_quit.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga + Copyright (C) 1997-2026 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_rwops.h b/include/SDL/SDL_rwops.h index 5b2bb5539..98788f0c0 100644 --- a/include/SDL/SDL_rwops.h +++ b/include/SDL/SDL_rwops.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga + Copyright (C) 1997-2026 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_stdinc.h b/include/SDL/SDL_stdinc.h index da7e7624e..5f832de75 100644 --- a/include/SDL/SDL_stdinc.h +++ b/include/SDL/SDL_stdinc.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga + Copyright (C) 1997-2026 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_syswm.h b/include/SDL/SDL_syswm.h index c32f7f398..9284b8b2e 100644 --- a/include/SDL/SDL_syswm.h +++ b/include/SDL/SDL_syswm.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga + Copyright (C) 1997-2026 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_thread.h b/include/SDL/SDL_thread.h index dca94836a..f3999bf90 100644 --- a/include/SDL/SDL_thread.h +++ b/include/SDL/SDL_thread.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga + Copyright (C) 1997-2026 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_timer.h b/include/SDL/SDL_timer.h index 611eb5866..56f3ee1d7 100644 --- a/include/SDL/SDL_timer.h +++ b/include/SDL/SDL_timer.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga + Copyright (C) 1997-2026 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_types.h b/include/SDL/SDL_types.h index 3db709c2a..885ff883c 100644 --- a/include/SDL/SDL_types.h +++ b/include/SDL/SDL_types.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga + Copyright (C) 1997-2026 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_version.h b/include/SDL/SDL_version.h index 3c948bc68..c43015023 100644 --- a/include/SDL/SDL_version.h +++ b/include/SDL/SDL_version.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga + Copyright (C) 1997-2026 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/SDL_video.h b/include/SDL/SDL_video.h index 409764d14..01f23b06c 100644 --- a/include/SDL/SDL_video.h +++ b/include/SDL/SDL_video.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga + Copyright (C) 1997-2026 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/begin_code.h b/include/SDL/begin_code.h index db140993e..08aa90ad4 100644 --- a/include/SDL/begin_code.h +++ b/include/SDL/begin_code.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga + Copyright (C) 1997-2026 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL/close_code.h b/include/SDL/close_code.h index bdcde99b4..1a99ffa17 100644 --- a/include/SDL/close_code.h +++ b/include/SDL/close_code.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga + Copyright (C) 1997-2026 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 72af0fb46..44bd0f2ba 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga + Copyright (C) 1997-2026 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/SDL12_compat_objc.m b/src/SDL12_compat_objc.m index 8f4228874..80906e710 100644 --- a/src/SDL12_compat_objc.m +++ b/src/SDL12_compat_objc.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga + Copyright (C) 1997-2026 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/SDL20_include_wrapper.h b/src/SDL20_include_wrapper.h index 32d24b137..e53cc8094 100644 --- a/src/SDL20_include_wrapper.h +++ b/src/SDL20_include_wrapper.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga + Copyright (C) 1997-2026 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/SDL20_syms.h b/src/SDL20_syms.h index 5f1a2c9cb..23b8bcc52 100644 --- a/src/SDL20_syms.h +++ b/src/SDL20_syms.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga + Copyright (C) 1997-2026 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/default_cursor.h b/src/default_cursor.h index 9c93666d3..82f2a46d2 100644 --- a/src/default_cursor.h +++ b/src/default_cursor.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga + Copyright (C) 1997-2026 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/version.rc b/src/version.rc index 7a42fb868..ce9a41c70 100644 --- a/src/version.rc +++ b/src/version.rc @@ -19,7 +19,7 @@ BEGIN VALUE "FileDescription", "SDL\0" VALUE "FileVersion", "1, 2, 73, 0\0" VALUE "InternalName", "SDL\0" - VALUE "LegalCopyright", "Copyright (C) 2025 Sam Lantinga\0" + VALUE "LegalCopyright", "Copyright (C) 2026 Sam Lantinga\0" VALUE "OriginalFilename", "SDL.dll\0" VALUE "ProductName", "Simple DirectMedia Layer 1.2 wrapper\0" VALUE "ProductVersion", "1, 2, 73, 0\0" diff --git a/src/x86_msvc.h b/src/x86_msvc.h index a25f5be26..d241d0293 100644 --- a/src/x86_msvc.h +++ b/src/x86_msvc.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga + Copyright (C) 1997-2026 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages From 0ea5b381a3b95308852bd70e5c6a418381035bce Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 8 Jan 2026 12:38:09 -0500 Subject: [PATCH 586/606] video: Don't tear everything down in SDL_SetVideoMode software surface changes. This is noticable in, for example, Loki's port of Sid Meier's Alpha Centauri, where it wants to show static Loki/Firaxis logos on an 8-bit screen surface, then set the video mode to 16-bit for intro videos through SMPEG, then back to an 8-bit surface for the main menu and gameplay. Before this, windows would be destroyed and immediately pop back up: an unnecessary visual glitch, but also it caused rendering to fail on at least one system. Since software surfaces already go through a conversion to whatever format the SDL2 renderer's texture wants, it was better to avoid all the damage by letting the conversion surface absorb the format change. Fixes #389. --- src/SDL12_compat.c | 40 ++++++++++++++++++++++++---------------- src/SDL20_syms.h | 1 + 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 44bd0f2ba..db9f4092e 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -6515,8 +6515,8 @@ SetVideoModeImpl(int width, int height, int bpp, Uint32 flags12) if (VideoSurface12->surface20 && ((VideoSurface12->flags & SDL12_OPENGL) != (flags12 & SDL12_OPENGL))) { EndVidModeCreate(); /* rebuild the window if moving to/from a GL context */ - } else if (VideoSurface12->surface20 && (VideoSurface12->surface20->format->format != appfmt)) { - EndVidModeCreate(); /* rebuild the window if changing pixel format */ + } else if ((flags12 & SDL12_OPENGL) && VideoSurface12->surface20 && (VideoSurface12->surface20->format->format != appfmt)) { + EndVidModeCreate(); /* rebuild the window if changing pixel format on an OpenGL surface */ } else if (DesiredRefreshRate != CurrentRefreshRate) { EndVidModeCreate(); /* rebuild the window if changing refresh rate */ } else { @@ -6525,7 +6525,7 @@ SetVideoModeImpl(int width, int height, int bpp, Uint32 flags12) /* The windx5 driver _always_ destroyed the window, unconditionally, but the default (windib) did not, so match windib. * windib: keep if: * - window already exists - * - BitsPerPixel hasn't changed + * - BitsPerPixel hasn't changed (in OpenGL mode; for software we don't care about the format change). * - none of the window flags (except SDL_ANYFORMAT) have changed * - window is already SDL_OPENGL. * - window is not a fullscreen window. @@ -6533,7 +6533,7 @@ SetVideoModeImpl(int width, int height, int bpp, Uint32 flags12) const Uint32 important_flags = ~(SDL12_PREALLOC | SDL12_ANYFORMAT); const SDL_bool recreate_window = ( ((VideoSurface12->flags & important_flags) != (flags12 & important_flags)) || - (!VideoSurface12->format || (VideoSurface12->format->BitsPerPixel != bpp)) || + ((flags12 & SDL12_OPENGL) && (!VideoSurface12->format || (VideoSurface12->format->BitsPerPixel != bpp))) || ((flags12 & SDL12_FULLSCREEN) == SDL12_FULLSCREEN) ) ? SDL_TRUE : SDL_FALSE; #elif defined(__APPLE__) @@ -6547,12 +6547,12 @@ SetVideoModeImpl(int width, int height, int bpp, Uint32 flags12) * - window already exists * - window is already SDL_OPENGL. * - new flags also want SDL_OPENGL. - * - BitsPerPixel hasn't changed + * - BitsPerPixel hasn't changed (in OpenGL mode; for software we don't care about the format change). * - SDL_NOFRAME hasn't changed */ const SDL_bool recreate_window = ( ((VideoSurface12->flags & SDL12_OPENGL) != (flags12 & SDL12_OPENGL)) || - (!VideoSurface12->format || (VideoSurface12->format->BitsPerPixel != bpp)) || + ((flags12 & SDL12_OPENGL) && (!VideoSurface12->format || (VideoSurface12->format->BitsPerPixel != bpp))) || ((VideoSurface12->flags & SDL12_NOFRAME) != (flags12 & SDL12_NOFRAME)) ) ? SDL_TRUE : SDL_FALSE; #else @@ -6804,20 +6804,28 @@ SetVideoModeImpl(int width, int height, int bpp, Uint32 flags12) return EndVidModeCreate(); } - if (VideoTexture20) { - SDL20_DestroyTexture(VideoTexture20); + if (!VideoTexture20) { + SDL20_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, WantScaleMethodNearest ? "0" : "1"); + VideoTexture20 = SDL20_CreateTexture(VideoRenderer20, rinfo.texture_formats[0], SDL_TEXTUREACCESS_STREAMING, width, height); + SDL20_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, old_scale_quality); + if (!VideoTexture20) { + return EndVidModeCreate(); + } } - if (VideoConvertSurface20) { - SDL20_FreeSurface(VideoConvertSurface20); - VideoConvertSurface20 = NULL; + /* clear the texture for (re)use */ + { + SDL_Surface *surface = NULL; + if (SDL20_LockTextureToSurface(VideoTexture20, NULL, &surface) == 0) { + SDL20_FillRect(surface, NULL, SDL20_MapRGB(surface->format, 0, 0, 0)); + SDL20_UnlockTexture(VideoTexture20); + } } - SDL20_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, WantScaleMethodNearest ? "0" : "1"); - VideoTexture20 = SDL20_CreateTexture(VideoRenderer20, rinfo.texture_formats[0], SDL_TEXTUREACCESS_STREAMING, width, height); - SDL20_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, old_scale_quality); - if (!VideoTexture20) { - return EndVidModeCreate(); + /* don't need conversion, or need to change the conversion surface's format? Nuke the existing surface (and maybe rebuild it later). */ + if (VideoConvertSurface20 && ((rinfo.texture_formats[0] == appfmt) || (rinfo.texture_formats[0] != VideoConvertSurface20->format->format))) { + SDL20_FreeSurface(VideoConvertSurface20); + VideoConvertSurface20 = NULL; } if (rinfo.texture_formats[0] != appfmt) { diff --git a/src/SDL20_syms.h b/src/SDL20_syms.h index 23b8bcc52..f0ac1e91d 100644 --- a/src/SDL20_syms.h +++ b/src/SDL20_syms.h @@ -325,6 +325,7 @@ SDL20_SYM(void,RenderGetScale,(SDL_Renderer *a, float *b, float *c),(a,b,c),retu SDL20_SYM(void,RenderGetViewport,(SDL_Renderer *a, SDL_Rect *b),(a,b),return) SDL20_SYM(SDL_Texture *,CreateTexture,(SDL_Renderer *a, Uint32 b, int c, int d, int e),(a,b,c,d,e),return) SDL20_SYM(int,LockTexture,(SDL_Texture *a, const SDL_Rect *b, void **c, int *d),(a,b,c,d),return) +SDL20_SYM(int,LockTextureToSurface,(SDL_Texture *a, const SDL_Rect *b, SDL_Surface **c),(a,b,c),return) SDL20_SYM(void,UnlockTexture,(SDL_Texture *a),(a),) SDL20_SYM(int,UpdateTexture,(SDL_Texture *a, const SDL_Rect *b, const void *c, int d),(a,b,c,d),return) SDL20_SYM(int,UpdateYUVTexture,(SDL_Texture *a, const SDL_Rect *b, const Uint8 *c, int d, const Uint8 *e, int f, const Uint8 *g, int h),(a,b,c,d,e,f,g,h),return) From a3e9f2b618d8b7d5db2e4c3ad7b35367d7c3dc3b Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sat, 17 Jan 2026 05:10:00 +0300 Subject: [PATCH 587/606] updated dr_mp3.h from mainstream. --- src/dr_mp3.h | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/dr_mp3.h b/src/dr_mp3.h index a253c2298..f42023fa6 100644 --- a/src/dr_mp3.h +++ b/src/dr_mp3.h @@ -1,6 +1,6 @@ /* MP3 audio decoder. Choice of public domain or MIT-0. See license statements at the end of this file. -dr_mp3 - v0.7.3 - TBD +dr_mp3 - v0.7.3 - 2026-01-17 David Reid - mackron@gmail.com @@ -3188,7 +3188,6 @@ static drmp3_bool32 drmp3_init_internal(drmp3* pMP3, drmp3_read_proc onRead, drm { drmp3_bs bs; drmp3_L3_gr_info grInfo[4]; - const drmp3_uint8* pTagData = pFirstFrameData; drmp3_bs_init(&bs, pFirstFrameData + DRMP3_HDR_SIZE, firstFrameInfo.frame_bytes - DRMP3_HDR_SIZE); @@ -3199,6 +3198,7 @@ static drmp3_bool32 drmp3_init_internal(drmp3* pMP3, drmp3_read_proc onRead, drm if (drmp3_L3_read_side_info(&bs, grInfo, pFirstFrameData) >= 0) { drmp3_bool32 isXing = DRMP3_FALSE; drmp3_bool32 isInfo = DRMP3_FALSE; + const drmp3_uint8* pTagData; const drmp3_uint8* pTagDataBeg; pTagDataBeg = pFirstFrameData + DRMP3_HDR_SIZE + (bs.pos/8); @@ -3349,8 +3349,6 @@ static drmp3_bool32 drmp3__on_seek_memory(void* pUserData, int byteOffset, drmp3 DRMP3_ASSERT(pMP3 != NULL); - newCursor = pMP3->memory.currentReadPos; - if (origin == DRMP3_SEEK_SET) { newCursor = 0; } else if (origin == DRMP3_SEEK_CUR) { @@ -5036,8 +5034,9 @@ DIFFERENCES BETWEEN minimp3 AND dr_mp3 /* REVISION HISTORY ================ -v0.7.3 - TBD +v0.7.3 - 2026-01-17 - Fix an error in drmp3_open_and_read_pcm_frames_s16() and family when memory allocation fails. + - Fix some compilation warnings. v0.7.2 - 2025-12-02 - Reduce stack space to improve robustness on embedded systems. From 424f7155ee86a32bbee339644f2439b642c34870 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sat, 24 Jan 2026 10:33:02 +0300 Subject: [PATCH 588/606] silence a Watcom C++ W472 warning SDL12_compat.c(3030): Warning! W472: col(165) expression with side effect in sizeof discarded --- src/SDL12_compat.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index db9f4092e..9e35e19c1 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -3026,8 +3026,9 @@ SDL_QuitSubSystem(Uint32 sdl12flags) DECLSPEC12 void SDLCALL SDL_Quit(void) { + SDL_bool noquitvideo = SDL12Compat_GetHintBoolean("SDL12COMPAT_NO_QUIT_VIDEO", SDL_FALSE); SDL_QuitSubSystem(SDL_WasInit(0) | SDL12_INIT_CDROM); - SDL_assert((InitializedSubsystems20 == 0) || (SDL12Compat_GetHintBoolean("SDL12COMPAT_NO_QUIT_VIDEO", SDL_FALSE) && (InitializedSubsystems20 == SDL_INIT_VIDEO))); + SDL_assert((InitializedSubsystems20 == 0) || (noquitvideo && (InitializedSubsystems20 == SDL_INIT_VIDEO))); } DECLSPEC12 void SDLCALL From e1c4dbfa9a171e4743a8f7135d58be228dff2b4a Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sat, 24 Jan 2026 10:33:02 +0300 Subject: [PATCH 589/606] silence a Watcom C++ W687 warning SDL12_compat.c(1171): Warning! W687: col(20) expression for 'while' is always true --- src/SDL12_compat.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 9e35e19c1..7a9c1ba68 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1168,11 +1168,12 @@ static int SDL12COMPAT_strlen(const char *str) /* you can use SDL20_strcmp once we're past startup. */ static SDL_bool SDL12COMPAT_strequal(const char *a, const char *b) { - while (SDL_TRUE) { + for ( ;; ) { const char cha = *a; if (cha != *b) { return SDL_FALSE; - } else if (!cha) { + } + if (!cha) { break; } a++; From 4a9f157ac8bc9ad776033ceee6da0b6fe67efe0d Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 29 Jan 2026 10:29:55 -0800 Subject: [PATCH 590/606] Fixed crash on Windows if the video driver hint isn't set Fixes https://github.com/libsdl-org/sdl12-compat/issues/390 --- src/SDL12_compat.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 7a9c1ba68..8329cf269 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -2799,7 +2799,9 @@ SDL_InitSubSystem(Uint32 sdl12flags) #ifdef __WINDOWS__ /* DOSBox (and probably other things), try to force the "windib" video backend, but it doesn't exist in SDL2. Force to "windows" instead. */ - if (videodriver && (SDL20_strcmp(videodriver, "windib") == 0) || (SDL20_strcmp(videodriver, "directx") == 0)) { + if (videodriver && + (SDL20_strcmp(videodriver, "windib") == 0 || + SDL20_strcmp(videodriver, "directx") == 0)) { videodriver = "windows"; } #endif From 8cb4550f9aff307e3df6ce628c2bb1287c6c105b Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 3 Feb 2026 14:14:26 -0800 Subject: [PATCH 591/606] Updated to version 1.2.74 for release --- CMakeLists.txt | 2 +- include/SDL/SDL_version.h | 2 +- src/Makefile.darwin | 2 +- src/Makefile.linux | 2 +- src/SDL12_compat.c | 2 +- src/version.rc | 8 ++++---- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 628a0f364..1d5bab9dc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ # cmake -DSDL2_INCLUDE_DIR=/opt/SDL2/include/SDL2 [other stuff] cmake_minimum_required(VERSION 3.0.0...4.1) -project(sdl12_compat VERSION 1.2.73 LANGUAGES C) +project(sdl12_compat VERSION 1.2.74 LANGUAGES C) option(SDL12TESTS "Enable to build SDL-1.2 test programs" ON) option(SDL12DEVEL "Enable installing SDL-1.2 development headers" ON) diff --git a/include/SDL/SDL_version.h b/include/SDL/SDL_version.h index c43015023..6556b8987 100644 --- a/include/SDL/SDL_version.h +++ b/include/SDL/SDL_version.h @@ -33,7 +33,7 @@ real SDL-1.2 available to you. */ /* We bumped the patchlevel to 50 for sdl12-compat */ #define SDL_MAJOR_VERSION 1 #define SDL_MINOR_VERSION 2 -#define SDL_PATCHLEVEL 73 +#define SDL_PATCHLEVEL 74 typedef struct SDL_version { diff --git a/src/Makefile.darwin b/src/Makefile.darwin index ded709ad6..b1ea38c7a 100644 --- a/src/Makefile.darwin +++ b/src/Makefile.darwin @@ -18,7 +18,7 @@ CFLAGS = -mmacosx-version-min=10.6 -fPIC -O3 -Wall LDFLAGS = -mmacosx-version-min=10.6 -dynamiclib -Wl,-undefined,error -Wl,-single_module #LDFLAGS+= -Wl,-headerpad_max_install_names LDFLAGS+= -Wl,-install_name,"/usr/local/lib/$(DYLIB)" -LDFLAGS+= -Wl,-compatibility_version,1.0 -Wl,-current_version,12.73 +LDFLAGS+= -Wl,-compatibility_version,1.0 -Wl,-current_version,12.74 LDLIBS = -Wl,-framework,AppKit # this is needed for x86_64 - cross-gcc might not add it. #LDLIBS += -Wl,-lbundle1.o diff --git a/src/Makefile.linux b/src/Makefile.linux index 70c152047..0329737ee 100644 --- a/src/Makefile.linux +++ b/src/Makefile.linux @@ -16,7 +16,7 @@ LDFLAGS = -shared -Wl,-soname,libSDL-1.2.so.0 LDFLAGS+= -Wl,--no-undefined LDLIBS = -ldl -SHLIB = libSDL-1.2.so.1.2.73 +SHLIB = libSDL-1.2.so.1.2.74 OBJ = SDL12_compat.o diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 8329cf269..78b58cdfe 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -28,7 +28,7 @@ * should be way ahead of what SDL-1.2 Classic would report, so apps can * decide if they're running under the compat layer, if they really care. */ -#define SDL12_COMPAT_VERSION 73 +#define SDL12_COMPAT_VERSION 74 #include #include diff --git a/src/version.rc b/src/version.rc index ce9a41c70..9c70f7f24 100644 --- a/src/version.rc +++ b/src/version.rc @@ -3,8 +3,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,2,73,0 - PRODUCTVERSION 1,2,73,0 + FILEVERSION 1,2,74,0 + PRODUCTVERSION 1,2,74,0 FILEFLAGSMASK 0x3fL FILEFLAGS 0x0L FILEOS 0x40004L @@ -17,12 +17,12 @@ BEGIN BEGIN VALUE "CompanyName", "\0" VALUE "FileDescription", "SDL\0" - VALUE "FileVersion", "1, 2, 73, 0\0" + VALUE "FileVersion", "1, 2, 74, 0\0" VALUE "InternalName", "SDL\0" VALUE "LegalCopyright", "Copyright (C) 2026 Sam Lantinga\0" VALUE "OriginalFilename", "SDL.dll\0" VALUE "ProductName", "Simple DirectMedia Layer 1.2 wrapper\0" - VALUE "ProductVersion", "1, 2, 73, 0\0" + VALUE "ProductVersion", "1, 2, 74, 0\0" END END BLOCK "VarFileInfo" From e677f477c862a066da7490097ce86dddadd086e3 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Wed, 4 Feb 2026 10:23:51 -0800 Subject: [PATCH 592/606] Updated to version 1.2.75 for development --- CMakeLists.txt | 2 +- include/SDL/SDL_version.h | 2 +- src/Makefile.darwin | 2 +- src/Makefile.linux | 2 +- src/SDL12_compat.c | 2 +- src/version.rc | 8 ++++---- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1d5bab9dc..d9b4cd43a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ # cmake -DSDL2_INCLUDE_DIR=/opt/SDL2/include/SDL2 [other stuff] cmake_minimum_required(VERSION 3.0.0...4.1) -project(sdl12_compat VERSION 1.2.74 LANGUAGES C) +project(sdl12_compat VERSION 1.2.75 LANGUAGES C) option(SDL12TESTS "Enable to build SDL-1.2 test programs" ON) option(SDL12DEVEL "Enable installing SDL-1.2 development headers" ON) diff --git a/include/SDL/SDL_version.h b/include/SDL/SDL_version.h index 6556b8987..2c4fb050b 100644 --- a/include/SDL/SDL_version.h +++ b/include/SDL/SDL_version.h @@ -33,7 +33,7 @@ real SDL-1.2 available to you. */ /* We bumped the patchlevel to 50 for sdl12-compat */ #define SDL_MAJOR_VERSION 1 #define SDL_MINOR_VERSION 2 -#define SDL_PATCHLEVEL 74 +#define SDL_PATCHLEVEL 75 typedef struct SDL_version { diff --git a/src/Makefile.darwin b/src/Makefile.darwin index b1ea38c7a..a3e2c0309 100644 --- a/src/Makefile.darwin +++ b/src/Makefile.darwin @@ -18,7 +18,7 @@ CFLAGS = -mmacosx-version-min=10.6 -fPIC -O3 -Wall LDFLAGS = -mmacosx-version-min=10.6 -dynamiclib -Wl,-undefined,error -Wl,-single_module #LDFLAGS+= -Wl,-headerpad_max_install_names LDFLAGS+= -Wl,-install_name,"/usr/local/lib/$(DYLIB)" -LDFLAGS+= -Wl,-compatibility_version,1.0 -Wl,-current_version,12.74 +LDFLAGS+= -Wl,-compatibility_version,1.0 -Wl,-current_version,12.75 LDLIBS = -Wl,-framework,AppKit # this is needed for x86_64 - cross-gcc might not add it. #LDLIBS += -Wl,-lbundle1.o diff --git a/src/Makefile.linux b/src/Makefile.linux index 0329737ee..05e246873 100644 --- a/src/Makefile.linux +++ b/src/Makefile.linux @@ -16,7 +16,7 @@ LDFLAGS = -shared -Wl,-soname,libSDL-1.2.so.0 LDFLAGS+= -Wl,--no-undefined LDLIBS = -ldl -SHLIB = libSDL-1.2.so.1.2.74 +SHLIB = libSDL-1.2.so.1.2.75 OBJ = SDL12_compat.o diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 78b58cdfe..f90529335 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -28,7 +28,7 @@ * should be way ahead of what SDL-1.2 Classic would report, so apps can * decide if they're running under the compat layer, if they really care. */ -#define SDL12_COMPAT_VERSION 74 +#define SDL12_COMPAT_VERSION 75 #include #include diff --git a/src/version.rc b/src/version.rc index 9c70f7f24..9781e932a 100644 --- a/src/version.rc +++ b/src/version.rc @@ -3,8 +3,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,2,74,0 - PRODUCTVERSION 1,2,74,0 + FILEVERSION 1,2,75,0 + PRODUCTVERSION 1,2,75,0 FILEFLAGSMASK 0x3fL FILEFLAGS 0x0L FILEOS 0x40004L @@ -17,12 +17,12 @@ BEGIN BEGIN VALUE "CompanyName", "\0" VALUE "FileDescription", "SDL\0" - VALUE "FileVersion", "1, 2, 74, 0\0" + VALUE "FileVersion", "1, 2, 75, 0\0" VALUE "InternalName", "SDL\0" VALUE "LegalCopyright", "Copyright (C) 2026 Sam Lantinga\0" VALUE "OriginalFilename", "SDL.dll\0" VALUE "ProductName", "Simple DirectMedia Layer 1.2 wrapper\0" - VALUE "ProductVersion", "1, 2, 74, 0\0" + VALUE "ProductVersion", "1, 2, 75, 0\0" END END BLOCK "VarFileInfo" From d19329e574fff41ec8cd85d843c6f6ddeac75e61 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 1 Apr 2026 10:34:06 -0400 Subject: [PATCH 593/606] video: Rebuild screen surface in SDL_SetVideoMode when the window survives. Fixes #391. --- src/SDL12_compat.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index f90529335..6627e1cd3 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -6565,6 +6565,8 @@ SetVideoModeImpl(int width, int height, int bpp, Uint32 flags12) if (recreate_window) { EndVidModeCreate(); /* rebuild the window if we can't resize it. */ + } else if (!VideoSurface12->format || (VideoSurface12->format->BitsPerPixel != bpp)) { + FreeSurfaceContents(VideoSurface12); /* hollow out the 1.2 surface if the fomat changes, even if the window survives...so palettes, etc, get recreated. */ } } From 129e548169c56b9e9ed686e65e3509d4880d5502 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 1 Apr 2026 18:48:31 -0400 Subject: [PATCH 594/606] video: SDL_SetVideoMode should always reject bogus bpp arguments. Previously it would adjust it without failing if SDL_ANYFORMAT was set, but that was a misunderstanding of what this flag does; it decides if its okay to give you a shadow surface if you have an otherwise-reasonable bpp that the hardware doesn't support. Real SDL1.2 would fail with an error message with bpp=232 and flags=ANYFORMAT, as made clear to us by the tests for a perl SDL1 binding, so while this change makes sdl12-compat less forgiving, it makes it more _correct_ to what real 1.2 would do. --- src/SDL12_compat.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 6627e1cd3..01fab23aa 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -6505,12 +6505,8 @@ SetVideoModeImpl(int width, int height, int bpp, Uint32 flags12) } if ((bpp != 8) && (bpp != 16) && (bpp != 24) && (bpp != 32)) { - if (flags12 & SDL12_ANYFORMAT) { - bpp = max_bpp; - } else { - SDL20_SetError("Unsupported bits-per-pixel"); - return NULL; - } + SDL20_SetError("Invalid bits per pixel (range is {8...32})"); + return NULL; } appfmt = BPPToPixelFormat(bpp); From 8f1712499f400784d15a68b4c4392bed3f7248ad Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Thu, 2 Apr 2026 08:32:56 +0300 Subject: [PATCH 595/606] win32/SDL_win32_main.c: minor warning fix --- src/SDLmain/win32/SDL_win32_main.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/SDLmain/win32/SDL_win32_main.c b/src/SDLmain/win32/SDL_win32_main.c index 99ded4e4a..52727f0f3 100644 --- a/src/SDLmain/win32/SDL_win32_main.c +++ b/src/SDLmain/win32/SDL_win32_main.c @@ -104,9 +104,9 @@ static int ParseCommandLine(char *cmdline, char **argv) /* Strip out \ from \" sequences */ if( argv && last_argc != argc ) { - UnEscapeQuotes( argv[last_argc] ); + UnEscapeQuotes( argv[last_argc] ); } - last_argc = argc; + last_argc = argc; } if ( argv ) { argv[argc] = NULL; @@ -296,7 +296,7 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw) size_t nLen; /* Start up DDHELP.EXE before opening any files, so DDHELP doesn't - keep them open. This is a hack.. hopefully it will be fixed + keep them open. This is a hack.. hopefully it will be fixed someday. DDHELP.EXE starts up the first time DDRAW.DLL is loaded. */ handle = LoadLibrary(TEXT("DDRAW.DLL")); @@ -305,7 +305,7 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw) } /* Check for stdio redirect settings and do the redirection */ - if ((env_str = SDL_getenv("SDL_STDIO_REDIRECT"))) { + if ((env_str = SDL_getenv("SDL_STDIO_REDIRECT")) != NULL) { if (SDL_atoi(env_str)) { redirect_output(); } From c6e6bc68aac5f46e393ca31560fd0e976bf635d2 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 2 Apr 2026 10:39:27 -0700 Subject: [PATCH 596/606] Handle applications manually freeing surface pixels Fixes https://github.com/libsdl-org/sdl12-compat/issues/385 --- src/SDL12_compat.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 01fab23aa..3ea7f640f 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1475,6 +1475,9 @@ static QuirkEntryType quirks[] = { {"Jamestown-x86", "SDL12COMPAT_OPENGL_SCALING", "0"}, {"Jamestown-amd64", "SDL12COMPAT_OPENGL_SCALING", "0"}, + /* Sacred Gold manually frees SDL surface pixels */ + {"sacred", "SDL_SURFACE_MALLOC", "1"}, + #else /* TODO: Add any quirks needed for this system. */ @@ -2934,6 +2937,9 @@ static void FreeSurfaceContents(SDL12_Surface *surface12) { if (surface12->surface20) { + if (surface12->pixels == NULL) { + surface12->surface20->pixels = NULL; + } SDL20_FreeSurface(surface12->surface20); surface12->surface20 = NULL; } From 293b4cbd9eea61b18b9c9425d0c9200bff037360 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 3 Apr 2026 17:40:25 -0700 Subject: [PATCH 597/606] Updated to version 1.2.76 for release --- CMakeLists.txt | 4 ++-- include/SDL/SDL_version.h | 2 +- src/Makefile.darwin | 2 +- src/Makefile.linux | 2 +- src/Makefile.os2 | 2 +- src/Makefile.w32 | 2 +- src/SDL12_compat.c | 2 +- src/version.rc | 8 ++++---- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d9b4cd43a..5cc8c0506 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ # cmake -DSDL2_INCLUDE_DIR=/opt/SDL2/include/SDL2 [other stuff] cmake_minimum_required(VERSION 3.0.0...4.1) -project(sdl12_compat VERSION 1.2.75 LANGUAGES C) +project(sdl12_compat VERSION 1.2.76 LANGUAGES C) option(SDL12TESTS "Enable to build SDL-1.2 test programs" ON) option(SDL12DEVEL "Enable installing SDL-1.2 development headers" ON) @@ -33,7 +33,7 @@ if(APPLE) # Xcode project file uses 1.0.0, but it's more compatible to use the # higher version. set(DYLIB_COMPAT_VERSION 12.0.0 CACHE STRING "library compatibility version") - set(DYLIB_CURRENT_VERSION 12.73.0 CACHE STRING "library current version") + set(DYLIB_CURRENT_VERSION 12.76.0 CACHE STRING "library current version") include_directories("/opt/X11/include") # hack. if(CMAKE_VERSION VERSION_LESS 3.9) else() diff --git a/include/SDL/SDL_version.h b/include/SDL/SDL_version.h index 2c4fb050b..82932cf98 100644 --- a/include/SDL/SDL_version.h +++ b/include/SDL/SDL_version.h @@ -33,7 +33,7 @@ real SDL-1.2 available to you. */ /* We bumped the patchlevel to 50 for sdl12-compat */ #define SDL_MAJOR_VERSION 1 #define SDL_MINOR_VERSION 2 -#define SDL_PATCHLEVEL 75 +#define SDL_PATCHLEVEL 76 typedef struct SDL_version { diff --git a/src/Makefile.darwin b/src/Makefile.darwin index a3e2c0309..24b799e73 100644 --- a/src/Makefile.darwin +++ b/src/Makefile.darwin @@ -18,7 +18,7 @@ CFLAGS = -mmacosx-version-min=10.6 -fPIC -O3 -Wall LDFLAGS = -mmacosx-version-min=10.6 -dynamiclib -Wl,-undefined,error -Wl,-single_module #LDFLAGS+= -Wl,-headerpad_max_install_names LDFLAGS+= -Wl,-install_name,"/usr/local/lib/$(DYLIB)" -LDFLAGS+= -Wl,-compatibility_version,1.0 -Wl,-current_version,12.75 +LDFLAGS+= -Wl,-compatibility_version,1.0 -Wl,-current_version,12.76 LDLIBS = -Wl,-framework,AppKit # this is needed for x86_64 - cross-gcc might not add it. #LDLIBS += -Wl,-lbundle1.o diff --git a/src/Makefile.linux b/src/Makefile.linux index 05e246873..35ec7cce9 100644 --- a/src/Makefile.linux +++ b/src/Makefile.linux @@ -16,7 +16,7 @@ LDFLAGS = -shared -Wl,-soname,libSDL-1.2.so.0 LDFLAGS+= -Wl,--no-undefined LDLIBS = -ldl -SHLIB = libSDL-1.2.so.1.2.75 +SHLIB = libSDL-1.2.so.1.2.76 OBJ = SDL12_compat.o diff --git a/src/Makefile.os2 b/src/Makefile.os2 index ac17dfa99..c2cc7ae8c 100644 --- a/src/Makefile.os2 +++ b/src/Makefile.os2 @@ -5,7 +5,7 @@ !endif DLLNAME = SDL12 -VERSION = 1.2.73 +VERSION = 1.2.76 # change SDL2INC to point to the SDL2 headers SDL2INC = include diff --git a/src/Makefile.w32 b/src/Makefile.w32 index 455f71796..3d73be896 100644 --- a/src/Makefile.w32 +++ b/src/Makefile.w32 @@ -5,7 +5,7 @@ !endif DLLNAME = SDL -VERSION = 1.2.73 +VERSION = 1.2.76 # change SDL2INC to point to the SDL2 headers SDL2INC = include diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 3ea7f640f..abc9e016f 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -28,7 +28,7 @@ * should be way ahead of what SDL-1.2 Classic would report, so apps can * decide if they're running under the compat layer, if they really care. */ -#define SDL12_COMPAT_VERSION 75 +#define SDL12_COMPAT_VERSION 76 #include #include diff --git a/src/version.rc b/src/version.rc index 9781e932a..ec0c033a2 100644 --- a/src/version.rc +++ b/src/version.rc @@ -3,8 +3,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,2,75,0 - PRODUCTVERSION 1,2,75,0 + FILEVERSION 1,2,76,0 + PRODUCTVERSION 1,2,76,0 FILEFLAGSMASK 0x3fL FILEFLAGS 0x0L FILEOS 0x40004L @@ -17,12 +17,12 @@ BEGIN BEGIN VALUE "CompanyName", "\0" VALUE "FileDescription", "SDL\0" - VALUE "FileVersion", "1, 2, 75, 0\0" + VALUE "FileVersion", "1, 2, 76, 0\0" VALUE "InternalName", "SDL\0" VALUE "LegalCopyright", "Copyright (C) 2026 Sam Lantinga\0" VALUE "OriginalFilename", "SDL.dll\0" VALUE "ProductName", "Simple DirectMedia Layer 1.2 wrapper\0" - VALUE "ProductVersion", "1, 2, 75, 0\0" + VALUE "ProductVersion", "1, 2, 76, 0\0" END END BLOCK "VarFileInfo" From 5392f04612831c3954d12154420df0cb510ddf7d Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Fri, 1 May 2026 06:10:00 +0300 Subject: [PATCH 598/606] SDL_UpperBlit: fix an oversight in commit 61e247df for issue #244. Otherwise NULL pointer dereference can happen in PrepBlitDestRect() --- src/SDL12_compat.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index abc9e016f..f7c799709 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -7039,14 +7039,15 @@ SDL_UpperBlit(SDL12_Surface *src12, SDL12_Rect *srcrect12, SDL12_Surface *dst12, SDL_Rect srcrect20, dstrect20; int retval; - PrepBlitDestRect(&dstrect20, dst12, dstrect12); - if ((src12 == NULL) || (dst12 == NULL)) { return SDL20_SetError("SDL_UpperBlit: passed a NULL surface"); } if ((src12->pixels == NULL) || (dst12->pixels == NULL)) { return SDL20_SetError("SDL_UpperBlit: passed a surface with NULL pixels"); } + + PrepBlitDestRect(&dstrect20, dst12, dstrect12); + if (SaveDestAlpha(src12, dst12, &dstrect20, &dstalpha) < 0) { return -1; } From fa5f9612c7ec63e87eae8bdbea8a98f4e82b1927 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Mon, 11 May 2026 21:47:02 +0300 Subject: [PATCH 599/606] updated dr_mp3.h from mainstream. --- src/dr_mp3.h | 74 +++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 53 insertions(+), 21 deletions(-) diff --git a/src/dr_mp3.h b/src/dr_mp3.h index f42023fa6..60a6c55e9 100644 --- a/src/dr_mp3.h +++ b/src/dr_mp3.h @@ -1,6 +1,6 @@ /* MP3 audio decoder. Choice of public domain or MIT-0. See license statements at the end of this file. -dr_mp3 - v0.7.3 - 2026-01-17 +dr_mp3 - v0.7.4 - TBD David Reid - mackron@gmail.com @@ -78,7 +78,7 @@ extern "C" { #define DRMP3_VERSION_MAJOR 0 #define DRMP3_VERSION_MINOR 7 -#define DRMP3_VERSION_REVISION 3 +#define DRMP3_VERSION_REVISION 4 #define DRMP3_VERSION_STRING DRMP3_XSTRINGIFY(DRMP3_VERSION_MAJOR) "." DRMP3_XSTRINGIFY(DRMP3_VERSION_MINOR) "." DRMP3_XSTRINGIFY(DRMP3_VERSION_REVISION) #include /* For size_t. */ @@ -674,8 +674,10 @@ DRMP3_API const char* drmp3_version_string(void) #if !defined(DR_MP3_NO_SIMD) -#if !defined(DR_MP3_ONLY_SIMD) && (defined(_M_X64) || defined(__x86_64__) || defined(__aarch64__) || defined(_M_ARM64) || defined(_M_ARM64EC)) -/* x64 always have SSE2, arm64 always have neon, no need for generic code */ +#if !defined(DR_MP3_ONLY_SIMD) && ((defined(_MSC_VER) && _MSC_VER >= 1400) && defined(_M_X64)) || ((defined(__i386) || defined(_M_IX86) || defined(__i386__) || defined(__x86_64__)) && ((defined(_M_IX86_FP) && _M_IX86_FP == 2) || defined(__SSE2__))) +#define DR_MP3_ONLY_SIMD +#endif +#if !defined(DR_MP3_ONLY_SIMD) && (defined(__ARM_NEON) || defined(__aarch64__) || defined(_M_ARM64) || defined(_M_ARM64EC)) #define DR_MP3_ONLY_SIMD #endif @@ -3204,6 +3206,10 @@ static drmp3_bool32 drmp3_init_internal(drmp3* pMP3, drmp3_read_proc onRead, drm pTagDataBeg = pFirstFrameData + DRMP3_HDR_SIZE + (bs.pos/8); pTagData = pTagDataBeg; + if (firstFrameInfo.frame_bytes - (size_t)(pTagData - pFirstFrameData) < 8) { + goto done_xing_info; /* Frame too small for a Xing/Info tag. */ + } + /* Check for both "Xing" and "Info" identifiers. */ isXing = (pTagData[0] == 'X' && pTagData[1] == 'i' && pTagData[2] == 'n' && pTagData[3] == 'g'); isInfo = (pTagData[0] == 'I' && pTagData[1] == 'n' && pTagData[2] == 'f' && pTagData[3] == 'o'); @@ -3215,42 +3221,60 @@ static drmp3_bool32 drmp3_init_internal(drmp3* pMP3, drmp3_read_proc onRead, drm pTagData += 8; /* Skip past the ID and flags. */ if (flags & 0x01) { /* FRAMES flag. */ + if (firstFrameInfo.frame_bytes - (size_t)(pTagData - pFirstFrameData) < 4) { + goto done_xing_info; /* Invalid Xing/Info tag. */ + } + detectedMP3FrameCount = (drmp3_uint32)pTagData[0] << 24 | (drmp3_uint32)pTagData[1] << 16 | (drmp3_uint32)pTagData[2] << 8 | (drmp3_uint32)pTagData[3]; pTagData += 4; } if (flags & 0x02) { /* BYTES flag. */ + if (firstFrameInfo.frame_bytes - (size_t)(pTagData - pFirstFrameData) < 4) { + goto done_xing_info; /* Invalid Xing/Info tag. */ + } + bytes = (drmp3_uint32)pTagData[0] << 24 | (drmp3_uint32)pTagData[1] << 16 | (drmp3_uint32)pTagData[2] << 8 | (drmp3_uint32)pTagData[3]; (void)bytes; /* <-- Just to silence a warning about `bytes` being assigned but unused. Want to leave this here in case I want to make use of it later. */ pTagData += 4; } if (flags & 0x04) { /* TOC flag. */ + if (firstFrameInfo.frame_bytes - (size_t)(pTagData - pFirstFrameData) < 100) { + goto done_xing_info; /* Invalid Xing/Info tag. */ + } + /* TODO: Extract and bind seek points. */ pTagData += 100; } if (flags & 0x08) { /* SCALE flag. */ + if (firstFrameInfo.frame_bytes - (size_t)(pTagData - pFirstFrameData) < 4) { + goto done_xing_info; /* Invalid Xing/Info tag. */ + } + pTagData += 4; } /* At this point we're done with the Xing/Info header. Now we can look at the LAME data. */ if (pTagData[0]) { - pTagData += 21; + int delayInPCMFrames; + int paddingInPCMFrames; - if (pTagData - pFirstFrameData + 14 < firstFrameInfo.frame_bytes) { - int delayInPCMFrames; - int paddingInPCMFrames; + if (firstFrameInfo.frame_bytes - (size_t)(pTagData - pFirstFrameData) < 36) { + goto done_xing_info; /* Invalid Xing/Info tag. */ + } - delayInPCMFrames = (( (drmp3_uint32)pTagData[0] << 4) | ((drmp3_uint32)pTagData[1] >> 4)) + (528 + 1); - paddingInPCMFrames = ((((drmp3_uint32)pTagData[1] & 0xF) << 8) | ((drmp3_uint32)pTagData[2] )) - (528 + 1); - if (paddingInPCMFrames < 0) { - paddingInPCMFrames = 0; /* Padding cannot be negative. Probably a malformed file. Ignore. */ - } - - pMP3->delayInPCMFrames = (drmp3_uint32)delayInPCMFrames; - pMP3->paddingInPCMFrames = (drmp3_uint32)paddingInPCMFrames; + pTagData += 21; + + delayInPCMFrames = (( (drmp3_uint32)pTagData[0] << 4) | ((drmp3_uint32)pTagData[1] >> 4)) + (528 + 1); + paddingInPCMFrames = ((((drmp3_uint32)pTagData[1] & 0xF) << 8) | ((drmp3_uint32)pTagData[2] )) - (528 + 1); + if (paddingInPCMFrames < 0) { + paddingInPCMFrames = 0; /* Padding cannot be negative. Probably a malformed file. Ignore. */ } + + pMP3->delayInPCMFrames = (drmp3_uint32)delayInPCMFrames; + pMP3->paddingInPCMFrames = (drmp3_uint32)paddingInPCMFrames; } /* @@ -3289,6 +3313,8 @@ static drmp3_bool32 drmp3_init_internal(drmp3* pMP3, drmp3_read_proc onRead, drm */ drmp3dec_init(&pMP3->decoder); } + + done_xing_info:; } else { /* Failed to read the side info. */ } @@ -3301,7 +3327,7 @@ static drmp3_bool32 drmp3_init_internal(drmp3* pMP3, drmp3_read_proc onRead, drm } if (detectedMP3FrameCount != 0xFFFFFFFF) { - pMP3->totalPCMFrameCount = detectedMP3FrameCount * firstFramePCMFrameCount; + pMP3->totalPCMFrameCount = (drmp3_uint64)detectedMP3FrameCount * firstFramePCMFrameCount; } pMP3->channels = pMP3->mp3FrameChannels; @@ -4264,7 +4290,7 @@ DRMP3_API drmp3_uint64 drmp3_read_pcm_frames_f32(drmp3* pMP3, drmp3_uint64 frame #else /* Slow path. Convert from s16 to f32. */ { - drmp3_int16 pTempS16[8192]; + drmp3_int16 pTempS16[1152*2]; /* MP3 frames have a maximum per-channel sample count of 1152. Times 2 to account for stereo. */ drmp3_uint64 totalPCMFramesRead = 0; while (totalPCMFramesRead < framesToRead) { @@ -4302,7 +4328,7 @@ DRMP3_API drmp3_uint64 drmp3_read_pcm_frames_s16(drmp3* pMP3, drmp3_uint64 frame #else /* Slow path. Convert from f32 to s16. */ { - float pTempF32[4096]; + float pTempF32[1152*2]; /* MP3 frames have a maximum per-channel sample count of 1152. Times 2 to account for stereo. */ drmp3_uint64 totalPCMFramesRead = 0; while (totalPCMFramesRead < framesToRead) { @@ -4791,7 +4817,7 @@ static float* drmp3__full_read_and_close_f32(drmp3* pMP3, drmp3_config* pConfig, drmp3_uint64 totalFramesRead = 0; drmp3_uint64 framesCapacity = 0; float* pFrames = NULL; - float temp[4096]; + float temp[1152*2]; /* MP3 frames have a maximum per-channel sample count of 1152. Times 2 to account for stereo. */ DRMP3_ASSERT(pMP3 != NULL); @@ -4861,7 +4887,7 @@ static drmp3_int16* drmp3__full_read_and_close_s16(drmp3* pMP3, drmp3_config* pC drmp3_uint64 totalFramesRead = 0; drmp3_uint64 framesCapacity = 0; drmp3_int16* pFrames = NULL; - drmp3_int16 temp[4096]; + drmp3_int16 temp[1152*2]; /* MP3 frames have a maximum per-channel sample count of 1152. Times 2 to account for stereo. */ DRMP3_ASSERT(pMP3 != NULL); @@ -5034,6 +5060,12 @@ DIFFERENCES BETWEEN minimp3 AND dr_mp3 /* REVISION HISTORY ================ +v0.7.4 - TBD + - Fix an overflow error with "Xing" and "Info" tag parsing. + - Add some validation checks for "Xing" and "Info" tag parsing. + - Reduce size of some stack allocations. + - Improvements to SIMD detection. + v0.7.3 - 2026-01-17 - Fix an error in drmp3_open_and_read_pcm_frames_s16() and family when memory allocation fails. - Fix some compilation warnings. From 2c13ce717592d347e6af07315a9a4ef84f148e6a Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Mon, 25 May 2026 18:40:20 +0300 Subject: [PATCH 600/606] _uitoa does not exist --- include/SDL/SDL_config.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/SDL/SDL_config.h b/include/SDL/SDL_config.h index f8185219b..9d7710e3b 100644 --- a/include/SDL/SDL_config.h +++ b/include/SDL/SDL_config.h @@ -147,7 +147,6 @@ stage, though. Send patches if your platform lacks something. */ #define HAVE_RINDEX 1 #define HAVE_ITOA 1 #define HAVE__LTOA 1 -#define HAVE__UITOA 1 #define HAVE__ULTOA 1 #define HAVE__I64TOA 1 #define HAVE__UI64TOA 1 From 9a016c0e73675cf9d80b8b971289edbc0d832fe8 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 8 Jun 2026 17:19:41 -0400 Subject: [PATCH 601/606] quirks: Penumbra: Overture doesn't like GL scaling. We probably need to add this quirk for Linux and Mac, too, but I need the exe names for those platforms. Reference Issue #395. --- src/SDL12_compat.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index f7c799709..9da6f3318 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1478,6 +1478,10 @@ static QuirkEntryType quirks[] = { /* Sacred Gold manually frees SDL surface pixels */ {"sacred", "SDL_SURFACE_MALLOC", "1"}, +#elif defined(_WIN32) + // Penumbra: Overture doesn't like GL scaling. + {"Penumbra.exe", "SDL12COMPAT_OPENGL_SCALING", "0"}, + #else /* TODO: Add any quirks needed for this system. */ From 04ba42c412991558a39a3bd7651b20f756c380c5 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sat, 13 Jun 2026 08:33:20 +0300 Subject: [PATCH 602/606] tweak SDL12COMPAT_strlen() / volatile hack to be c++-23 compatible. Reference issue: https://github.com/libsdl-org/sdl2-compat/issues/340. --- src/SDL12_compat.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 9da6f3318..d0da6dbbb 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1158,11 +1158,11 @@ SDL12COMPAT_itoa(char *dst, int val) /* you can use SDL20_strlen once we're past startup. */ static int SDL12COMPAT_strlen(const char *str) { - volatile int retval = 0; /* volatile prevents gcc from optimizing this into strlen() */ - while (str[retval]) { - retval++; + volatile const char *ptr = str; + while (*ptr) { + ++ptr; } - return retval; + return (int)(ptr - str); } /* you can use SDL20_strcmp once we're past startup. */ From 8b3be24e25aecea84bb9ccc027fa71118a92fb6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Noel?= Date: Tue, 23 Jun 2026 11:27:51 +0200 Subject: [PATCH 603/606] quirks: force SDL_VIDEODRIVER to x11 for 2 oldies from LGP --- src/SDL12_compat.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index d0da6dbbb..34635e27d 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1477,6 +1477,10 @@ static QuirkEntryType quirks[] = { /* Sacred Gold manually frees SDL surface pixels */ {"sacred", "SDL_SURFACE_MALLOC", "1"}, + {"sacred", "SDL_VIDEODRIVER", "x11"}, + + /* Creatures Internet Edition calls SDL_GetWMInfo() and exit if it fails */ + {"lc2e", "SDL_VIDEODRIVER", "x11"}, #elif defined(_WIN32) // Penumbra: Overture doesn't like GL scaling. From d6360e19e63fe6af162f2e139502c9946203528f Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sun, 19 Jul 2026 05:15:32 +0300 Subject: [PATCH 604/606] dylib_locations[]: add missing trailing slash to "/Library/Frameworks" Fixes: https://github.com/libsdl-org/sdl12-compat/issues/398 --- src/SDL12_compat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c index 34635e27d..616a0ea4a 100644 --- a/src/SDL12_compat.c +++ b/src/SDL12_compat.c @@ -1304,7 +1304,7 @@ static char loaderror[256]; "@executable_path/" SDL20_LIBNAME2, /* MyApp.app/Contents/MacOS/libSDL2-2.0.dylib */ "@executable_path/../Frameworks/" SDL20_FRAMEWORK, /* MyApp.app/Contents/Frameworks/SDL2.framework */ NULL, /* /Users/username/Library/Frameworks/SDL2.framework */ - "/Library/Frameworks" SDL20_FRAMEWORK, /* /Library/Frameworks/SDL2.framework */ + "/Library/Frameworks/" SDL20_FRAMEWORK, /* /Library/Frameworks/SDL2.framework */ SDL20_LIBNAME, /* oh well, anywhere the system can see the .dylib (/usr/local/lib or whatever) */ SDL20_LIBNAME2 }; From 5a0aac8179e2ae4665e76c7c4f6ea89fe01145a7 Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Tue, 21 Jul 2026 14:33:40 +0300 Subject: [PATCH 605/606] update dr_mp3 from mainstream (Jul.15, 2026.) --- src/dr_mp3.h | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/src/dr_mp3.h b/src/dr_mp3.h index 60a6c55e9..9243b4c2a 100644 --- a/src/dr_mp3.h +++ b/src/dr_mp3.h @@ -3202,11 +3202,25 @@ static drmp3_bool32 drmp3_init_internal(drmp3* pMP3, drmp3_read_proc onRead, drm drmp3_bool32 isInfo = DRMP3_FALSE; const drmp3_uint8* pTagData; const drmp3_uint8* pTagDataBeg; + const void* pDataBufferEnd = NULL; + size_t frameBytes; pTagDataBeg = pFirstFrameData + DRMP3_HDR_SIZE + (bs.pos/8); pTagData = pTagDataBeg; - if (firstFrameInfo.frame_bytes - (size_t)(pTagData - pFirstFrameData) < 8) { + /* + We need to determine how many bytes are actually available in pTagData. Unfortunately this is different depending on + whether or not it's being decoded from memory or callbacks. + */ + if (pMP3->memory.pData != NULL && pMP3->memory.dataSize > 0) { + pDataBufferEnd = pMP3->memory.pData + pMP3->memory.dataSize; + } else { + pDataBufferEnd = pMP3->pData + pMP3->dataCapacity; + } + + frameBytes = DRMP3_MIN((size_t)firstFrameInfo.frame_bytes, (size_t)((drmp3_uint8*)pDataBufferEnd - pTagDataBeg)); + + if (frameBytes - (size_t)(pTagData - pFirstFrameData) < 8) { goto done_xing_info; /* Frame too small for a Xing/Info tag. */ } @@ -3221,7 +3235,7 @@ static drmp3_bool32 drmp3_init_internal(drmp3* pMP3, drmp3_read_proc onRead, drm pTagData += 8; /* Skip past the ID and flags. */ if (flags & 0x01) { /* FRAMES flag. */ - if (firstFrameInfo.frame_bytes - (size_t)(pTagData - pFirstFrameData) < 4) { + if (frameBytes - (size_t)(pTagData - pFirstFrameData) < 4) { goto done_xing_info; /* Invalid Xing/Info tag. */ } @@ -3230,7 +3244,7 @@ static drmp3_bool32 drmp3_init_internal(drmp3* pMP3, drmp3_read_proc onRead, drm } if (flags & 0x02) { /* BYTES flag. */ - if (firstFrameInfo.frame_bytes - (size_t)(pTagData - pFirstFrameData) < 4) { + if (frameBytes - (size_t)(pTagData - pFirstFrameData) < 4) { goto done_xing_info; /* Invalid Xing/Info tag. */ } @@ -3240,7 +3254,7 @@ static drmp3_bool32 drmp3_init_internal(drmp3* pMP3, drmp3_read_proc onRead, drm } if (flags & 0x04) { /* TOC flag. */ - if (firstFrameInfo.frame_bytes - (size_t)(pTagData - pFirstFrameData) < 100) { + if (frameBytes - (size_t)(pTagData - pFirstFrameData) < 100) { goto done_xing_info; /* Invalid Xing/Info tag. */ } @@ -3249,7 +3263,7 @@ static drmp3_bool32 drmp3_init_internal(drmp3* pMP3, drmp3_read_proc onRead, drm } if (flags & 0x08) { /* SCALE flag. */ - if (firstFrameInfo.frame_bytes - (size_t)(pTagData - pFirstFrameData) < 4) { + if (frameBytes - (size_t)(pTagData - pFirstFrameData) < 4) { goto done_xing_info; /* Invalid Xing/Info tag. */ } @@ -3261,7 +3275,7 @@ static drmp3_bool32 drmp3_init_internal(drmp3* pMP3, drmp3_read_proc onRead, drm int delayInPCMFrames; int paddingInPCMFrames; - if (firstFrameInfo.frame_bytes - (size_t)(pTagData - pFirstFrameData) < 36) { + if (frameBytes - (size_t)(pTagData - pFirstFrameData) < 36) { goto done_xing_info; /* Invalid Xing/Info tag. */ } From f39a989b1117510181380ea19a108876cc77b7b6 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 3 Sep 2026 12:53:15 -0400 Subject: [PATCH 606/606] policy: Added LLM policy. --- .github/PULL_REQUEST_TEMPLATE.md | 9 +++++++++ AGENTS.md | 11 +++++++++++ CLAUDE.md | 11 +++++++++++ 3 files changed, 31 insertions(+) create mode 100644 .github/PULL_REQUEST_TEMPLATE.md create mode 100644 AGENTS.md create mode 100644 CLAUDE.md diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 000000000..da33e1942 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,9 @@ +- [ ] I confirm that I am the author of this code and release it to the SDL project under the zlib license. This contribution does not contain code from other sources, including code generated by a Large Language Model ("AI"). + + + +## Description + + +## Existing Issue(s) + diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 000000000..f299237ae --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,11 @@ +Generative AI, including large language models (LLMs), should not be used in +any way when contributing to SDL. + +We want our code to be art. We want to interact with real humans. Please don't +submit AI-generated comments or code in bug reports or pull requests. We +understand some people consider AI to be a useful tool, but we want to connect +with you, not your computer. + +Any pull request to this project will ask you to confirm that you are the +author and that you are contributing your changes under the zlib license. + diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 000000000..f299237ae --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,11 @@ +Generative AI, including large language models (LLMs), should not be used in +any way when contributing to SDL. + +We want our code to be art. We want to interact with real humans. Please don't +submit AI-generated comments or code in bug reports or pull requests. We +understand some people consider AI to be a useful tool, but we want to connect +with you, not your computer. + +Any pull request to this project will ask you to confirm that you are the +author and that you are contributing your changes under the zlib license. +