From 390f3248f6a96c42513b838d5974c9906f261e6b Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 22 Sep 2017 11:57:35 -0700 Subject: [PATCH 01/95] Added tag release-2.0.6 for changeset 8df7a59b5528 --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index 461cbbbaa8..c39f995761 100644 --- a/.hgtags +++ b/.hgtags @@ -30,3 +30,4 @@ f285b9487756ff681f76c85644222c03a7bfa1c7 release-2.0.3 704a0bfecf754e4e1383f83c7d5118b00cae26ea release-2.0.3 e12c387305129c847b3928a123300b113782fe3f release-2.0.4 007dfe83abf81b1ff5df40186f65e8e64987b825 release-2.0.5 +8df7a59b55283aa09889522369a2b32674c048de release-2.0.6 From f168bbe4db18f84b59fed0932e8e75a2dabbf810 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 22 Sep 2017 12:26:54 -0700 Subject: [PATCH 02/95] Fixed bug 3837 - Change project settings for Xcode 9? Mark Callow Xcode 9 emits a warning to validate project settings. The changes it proposes are 1. [iOS] Update the iOS deployment target to 8.0 since Xcode does not support anything older. 2. [macOS] Target 'Framework' - Automatically Select Archectures. 3. [iOS & macOS] Turns on a bunch more compile warnings, a *lot* more on iOS. 4. [iOS & macOS] Turn on "Missing Localizability". I want to confirm if it is ok to accept these changes and submit updated project files. Since Alex Szpakowski has just removed iOS 7 guard ifdef's, I'm guessing 1 isn't a problem. 2 is probably ok for anyone building themselves. I wonder if it may cause problems for building distribution binaries. 3 shouldn't be a problem either provided any newly emitted warnings are fixed. 4 I am unfamiliar with. The description says "This will turn on the static analyzer to check for "Missing Localizability", because this project is localized for multiple languages." I suppose this may cause new warnings. --- Xcode-iOS/SDL/SDL.xcodeproj/project.pbxproj | 52 +++++++++++++++++++-- Xcode/SDL/SDL.xcodeproj/project.pbxproj | 18 +++++-- 2 files changed, 64 insertions(+), 6 deletions(-) diff --git a/Xcode-iOS/SDL/SDL.xcodeproj/project.pbxproj b/Xcode-iOS/SDL/SDL.xcodeproj/project.pbxproj index 19c472794a..efa00372c4 100755 --- a/Xcode-iOS/SDL/SDL.xcodeproj/project.pbxproj +++ b/Xcode-iOS/SDL/SDL.xcodeproj/project.pbxproj @@ -1236,7 +1236,7 @@ 29B97313FDCFA39411CA2CEA /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0800; + LastUpgradeCheck = 0900; TargetAttributes = { 00B4F48B12F6A69C0084EC00 = { DevelopmentTeam = UZ5V327NE3; @@ -1524,13 +1524,36 @@ C01FCF4F08A954540054247B /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; + GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_SYMBOLS_PRIVATE_EXTERN = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 5.1.1; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 6.1; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; @@ -1540,11 +1563,34 @@ C01FCF5008A954540054247B /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; GCC_SYMBOLS_PRIVATE_EXTERN = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 5.1.1; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 6.1; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; }; diff --git a/Xcode/SDL/SDL.xcodeproj/project.pbxproj b/Xcode/SDL/SDL.xcodeproj/project.pbxproj index 0f64bad0d9..856939f62e 100755 --- a/Xcode/SDL/SDL.xcodeproj/project.pbxproj +++ b/Xcode/SDL/SDL.xcodeproj/project.pbxproj @@ -2355,7 +2355,7 @@ 0867D690FE84028FC02AAC07 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0730; + LastUpgradeCheck = 0900; }; buildConfigurationList = 0073178E0858DB0500B2BC32 /* Build configuration list for PBXProject "SDL" */; compatibilityVersion = "Xcode 3.2"; @@ -2803,12 +2803,19 @@ 00CFA621106A567900758660 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; @@ -2836,7 +2843,6 @@ 00CFA622106A567900758660 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; CLANG_LINK_OBJC_RUNTIME = NO; COMBINE_HIDPI_IMAGES = YES; DYLIB_COMPATIBILITY_VERSION = 1.0.0; @@ -2888,12 +2894,19 @@ 00CFA627106A568900758660 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; @@ -2921,7 +2934,6 @@ 00CFA628106A568900758660 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; CLANG_LINK_OBJC_RUNTIME = NO; COMBINE_HIDPI_IMAGES = YES; DYLIB_COMPATIBILITY_VERSION = 1.0.0; From 5e921d60705bff4be130079c47d1f86e3ed2c3dd Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 22 Sep 2017 07:11:36 -0700 Subject: [PATCH 03/95] sdl - Fixing rendering borderless window. Need to force windows to send a WM_NCCALCSIZE then return 0 for non-client area size. - Adding WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX to borderless windows, for reasons noted in comments. - Fix SetupWindowData() setting SDL_WINDOW_BORDERLESS. This was being cleared at window creation, causing hanlding for the first WM_NCCALCSIZE message to fail --- src/video/windows/SDL_windowsevents.c | 9 ++++++++- src/video/windows/SDL_windowswindow.c | 16 ++++++++++++---- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/video/windows/SDL_windowsevents.c b/src/video/windows/SDL_windowsevents.c index cc6ef7e4a0..015ae88e2c 100644 --- a/src/video/windows/SDL_windowsevents.c +++ b/src/video/windows/SDL_windowsevents.c @@ -949,6 +949,14 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) } break; + case WM_NCCALCSIZE: + { + // When borderless, need to tell windows that the size of the non-client area is 0 + if ( wParam == TRUE && SDL_GetWindowFlags( data->window ) & SDL_WINDOW_BORDERLESS ) + return 0; + } + break; + case WM_NCHITTEST: { SDL_Window *window = data->window; @@ -976,7 +984,6 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) } } break; - } /* If there's a window proc, assume it's going to handle messages */ diff --git a/src/video/windows/SDL_windowswindow.c b/src/video/windows/SDL_windowswindow.c index 3bde2666fa..adbbe5367a 100644 --- a/src/video/windows/SDL_windowswindow.c +++ b/src/video/windows/SDL_windowswindow.c @@ -51,9 +51,14 @@ static WCHAR *SDL_HelperWindowClassName = TEXT("SDLHelperWindowInputCatcher"); static WCHAR *SDL_HelperWindowName = TEXT("SDLHelperWindowInputMsgWindow"); static ATOM SDL_HelperWindowClass = 0; +// for borderless Windows, still want the following flags: +// - WS_CAPTION: this seems to enable the Windows minimize animation +// - WS_SYSMENU: enables system context menu on task bar +// - WS_MINIMIZEBOX: window will respond to Windows minimize commands sent to all windows, such as windows key + m, shaking title bar, etc. + #define STYLE_BASIC (WS_CLIPSIBLINGS | WS_CLIPCHILDREN) #define STYLE_FULLSCREEN (WS_POPUP) -#define STYLE_BORDERLESS (WS_POPUP) +#define STYLE_BORDERLESS (WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX) #define STYLE_NORMAL (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX) #define STYLE_RESIZABLE (WS_THICKFRAME | WS_MAXIMIZEBOX) #define STYLE_MASK (STYLE_FULLSCREEN | STYLE_BORDERLESS | STYLE_NORMAL | STYLE_RESIZABLE) @@ -216,10 +221,10 @@ SetupWindowData(_THIS, SDL_Window * window, HWND hwnd, HWND parent, SDL_bool cre } else { window->flags &= ~SDL_WINDOW_SHOWN; } - if (style & (WS_BORDER | WS_THICKFRAME)) { - window->flags &= ~SDL_WINDOW_BORDERLESS; - } else { + if (style & WS_POPUP) { window->flags |= SDL_WINDOW_BORDERLESS; + } else { + window->flags &= ~SDL_WINDOW_BORDERLESS; } if (style & WS_THICKFRAME) { window->flags |= SDL_WINDOW_RESIZABLE; @@ -306,6 +311,9 @@ WIN_CreateWindow(_THIS, SDL_Window * window) return -1; } + // Inform Windows of the frame change so we can respond to WM_NCCALCSIZE + SetWindowPos( hwnd, NULL, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE ); + if (!(window->flags & SDL_WINDOW_OPENGL)) { return 0; } From 0e42161ab4c2bff8dc9169f817a4b5a532f9af97 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 22 Sep 2017 07:15:41 -0700 Subject: [PATCH 04/95] borderless windows will have WM_NCCALCSIZE return 0 for the non-client area. When this happens, it looks like windows will send a resize message expanding the window client area to the previous window + chrome size, so shouldn't need to adjust the window size for the set styles. --- src/video/windows/SDL_windowswindow.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/video/windows/SDL_windowswindow.c b/src/video/windows/SDL_windowswindow.c index adbbe5367a..50fdec9a19 100644 --- a/src/video/windows/SDL_windowswindow.c +++ b/src/video/windows/SDL_windowswindow.c @@ -94,7 +94,11 @@ WIN_AdjustWindowRectWithStyle(SDL_Window *window, DWORD style, BOOL menu, int *x rect.top = 0; rect.right = (use_current ? window->w : window->windowed.w); rect.bottom = (use_current ? window->h : window->windowed.h); - AdjustWindowRectEx(&rect, style, menu, 0); + + // borderless windows will have WM_NCCALCSIZE return 0 for the non-client area. When this happens, it looks like windows will send a resize message + // expanding the window client area to the previous window + chrome size, so shouldn't need to adjust the window size for the set styles. + if ( !(window->flags & SDL_WINDOW_BORDERLESS) ) + AdjustWindowRectEx( &rect, style, menu, 0 ); *x = (use_current ? window->x : window->windowed.x) + rect.left; *y = (use_current ? window->y : window->windowed.y) + rect.top; From 26ee8b5c8347040cfabc96c2e0e9c399c5e4e26c Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 22 Sep 2017 08:30:37 -0700 Subject: [PATCH 05/95] Guarded EGL code with SDL_VIDEO_OPENGL_EGL --- src/video/vivante/SDL_vivanteplatform.c | 10 ++++++++++ src/video/vivante/SDL_vivanteplatform.h | 2 ++ src/video/vivante/SDL_vivantevideo.c | 12 ++++++++++++ 3 files changed, 24 insertions(+) diff --git a/src/video/vivante/SDL_vivanteplatform.c b/src/video/vivante/SDL_vivanteplatform.c index d1b46a4949..694ed2614c 100644 --- a/src/video/vivante/SDL_vivanteplatform.c +++ b/src/video/vivante/SDL_vivanteplatform.c @@ -32,6 +32,16 @@ VIVANTE_SetupPlatform(_THIS) return 0; } +char *VIVANTE_GetDisplayName(_THIS) +{ + return NULL; +} + +void +VIVANTE_UpdateDisplayScale(_THIS) +{ +} + void VIVANTE_CleanupPlatform(_THIS) { diff --git a/src/video/vivante/SDL_vivanteplatform.h b/src/video/vivante/SDL_vivanteplatform.h index 23cb4062b5..9fa714b8d2 100644 --- a/src/video/vivante/SDL_vivanteplatform.h +++ b/src/video/vivante/SDL_vivanteplatform.h @@ -36,6 +36,8 @@ #endif extern int VIVANTE_SetupPlatform(_THIS); +extern char *VIVANTE_GetDisplayName(_THIS); +extern void VIVANTE_UpdateDisplayScale(_THIS); extern void VIVANTE_CleanupPlatform(_THIS); #endif /* SDL_VIDEO_DRIVER_VIVANTE */ diff --git a/src/video/vivante/SDL_vivantevideo.c b/src/video/vivante/SDL_vivantevideo.c index 79b36c258f..efa13c509c 100644 --- a/src/video/vivante/SDL_vivantevideo.c +++ b/src/video/vivante/SDL_vivantevideo.c @@ -97,6 +97,7 @@ VIVANTE_Create() device->DestroyWindow = VIVANTE_DestroyWindow; device->GetWindowWMInfo = VIVANTE_GetWindowWMInfo; +#if SDL_VIDEO_OPENGL_EGL device->GL_LoadLibrary = VIVANTE_GLES_LoadLibrary; device->GL_GetProcAddress = VIVANTE_GLES_GetProcAddress; device->GL_UnloadLibrary = VIVANTE_GLES_UnloadLibrary; @@ -106,6 +107,7 @@ VIVANTE_Create() device->GL_GetSwapInterval = VIVANTE_GLES_GetSwapInterval; device->GL_SwapWindow = VIVANTE_GLES_SwapWindow; device->GL_DeleteContext = VIVANTE_GLES_DeleteContext; +#endif device->PumpEvents = VIVANTE_PumpEvents; @@ -152,6 +154,9 @@ VIVANTE_AddVideoDisplays(_THIS) switch (bpp) { default: /* Is another format used? */ + case 32: + current_mode.format = SDL_PIXELFORMAT_ARGB8888; + break; case 16: current_mode.format = SDL_PIXELFORMAT_RGB565; break; @@ -160,6 +165,7 @@ VIVANTE_AddVideoDisplays(_THIS) current_mode.refresh_rate = 60; SDL_zero(display); + display.name = VIVANTE_GetDisplayName(_this); display.desktop_mode = current_mode; display.current_mode = current_mode; display.driverdata = data; @@ -208,6 +214,8 @@ VIVANTE_VideoInit(_THIS) return -1; } + VIVANTE_UpdateDisplayScale(_this); + #ifdef SDL_INPUT_LINUXEV if (SDL_EVDEV_Init() < 0) { return -1; @@ -281,6 +289,7 @@ VIVANTE_CreateWindow(_THIS, SDL_Window * window) return SDL_SetError("VIVANTE: Can't create native window"); } +#if SDL_VIDEO_OPENGL_EGL if (window->flags & SDL_WINDOW_OPENGL) { data->egl_surface = SDL_EGL_CreateSurface(_this, data->native_window); if (data->egl_surface == EGL_NO_SURFACE) { @@ -289,6 +298,7 @@ VIVANTE_CreateWindow(_THIS, SDL_Window * window) } else { data->egl_surface = EGL_NO_SURFACE; } +#endif /* Window has been successfully created */ return 0; @@ -302,9 +312,11 @@ VIVANTE_DestroyWindow(_THIS, SDL_Window * window) data = window->driverdata; if (data) { +#if SDL_VIDEO_OPENGL_EGL if (data->egl_surface != EGL_NO_SURFACE) { SDL_EGL_DestroySurface(_this, data->egl_surface); } +#endif if (data->native_window) { #if SDL_VIDEO_DRIVER_VIVANTE_VDK From 83451b2aeb581c447cdb53abf8eef74c77d7c72b Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 22 Sep 2017 08:30:46 -0700 Subject: [PATCH 06/95] Separated out SDL Android java code so audio, controller, and filesystem APIs can be used independently of the SDL activity, in Qt apps for example. --- .../src/org/libsdl/app/SDLActivity.java | 599 +----------------- src/core/android/SDL_android.c | 267 +++++--- 2 files changed, 186 insertions(+), 680 deletions(-) diff --git a/android-project/src/org/libsdl/app/SDLActivity.java b/android-project/src/org/libsdl/app/SDLActivity.java index d3da10e68e..ae18c572bb 100644 --- a/android-project/src/org/libsdl/app/SDLActivity.java +++ b/android-project/src/org/libsdl/app/SDLActivity.java @@ -56,24 +56,17 @@ public enum NativeState { public static boolean mSeparateMouseAndTouch; // Main components - protected static Context mContext; protected static SDLActivity mSingleton; protected static SDLSurface mSurface; protected static View mTextEdit; protected static boolean mScreenKeyboardShown; protected static ViewGroup mLayout; - protected static SDLJoystickHandler mJoystickHandler; - protected static SDLHapticHandler mHapticHandler; protected static SDLClipboardHandler mClipboardHandler; // This is what SDL runs in. It invokes SDL_main(), eventually protected static Thread mSDLThread; - // Audio - protected static AudioTrack mAudioTrack; - protected static AudioRecord mAudioRecord; - /** * This method returns the name of the shared object with the application entry point * It can be overridden by derived classes. @@ -136,17 +129,12 @@ protected String[] getArguments() { public static void initialize() { // The static nature of the singleton and Android quirkyness force us to initialize everything here // Otherwise, when exiting the app and returning to it, these variables *keep* their pre exit values - mContext = null; mSingleton = null; mSurface = null; mTextEdit = null; mLayout = null; - mJoystickHandler = null; - mHapticHandler = null; mClipboardHandler = null; mSDLThread = null; - mAudioTrack = null; - mAudioRecord = null; mExitCalledFromJava = false; mBrokenLibraries = false; mIsResumedCalled = false; @@ -157,9 +145,6 @@ public static void initialize() { } // Setup - public static void setContext(Context context) { - mContext = context; - } @Override protected void onCreate(Bundle savedInstanceState) { Log.v(TAG, "Device: " + android.os.Build.DEVICE); @@ -167,11 +152,6 @@ protected void onCreate(Bundle savedInstanceState) { Log.v(TAG, "onCreate()"); super.onCreate(savedInstanceState); - SDLActivity.initialize(); - - // So we can call stuff from static callbacks - mContext = mSingleton = this; - // Load shared libraries String errorMsgBrokenLib = ""; try { @@ -209,16 +189,14 @@ public void onClick(DialogInterface dialog,int id) { } // Set up JNI - SDLActivity.nativeSetupJNI(); + SDL.setupJNI(); - if (Build.VERSION.SDK_INT >= 16) { - mJoystickHandler = new SDLJoystickHandler_API16(); - } else if (Build.VERSION.SDK_INT >= 12) { - mJoystickHandler = new SDLJoystickHandler_API12(); - } else { - mJoystickHandler = new SDLJoystickHandler(); - } - mHapticHandler = new SDLHapticHandler(); + // Initialize state + SDL.initialize(); + + // So we can call stuff from static callbacks + mSingleton = this; + SDL.setContext(this); if (Build.VERSION.SDK_INT >= 11) { mClipboardHandler = new SDLClipboardHandler_API11(); @@ -461,7 +439,7 @@ protected boolean onUnhandledMessage(int command, Object param) { protected static class SDLCommandHandler extends Handler { @Override public void handleMessage(Message msg) { - Context context = getContext(); + Context context = SDL.getContext(); if (context == null) { Log.e(TAG, "error handling message, getContext() returned null"); return; @@ -529,12 +507,6 @@ boolean sendCommand(int command, Object data) { public static native void nativeResume(); public static native void onNativeDropFile(String filename); public static native void onNativeResize(int x, int y, int format, float rate); - public static native int onNativePadDown(int device_id, int keycode); - public static native int onNativePadUp(int device_id, int keycode); - public static native void onNativeJoy(int device_id, int axis, - float value); - public static native void onNativeHat(int device_id, int hat_id, - int x, int y); public static native void onNativeKeyDown(int keycode); public static native void onNativeKeyUp(int keycode); public static native void onNativeKeyboardFocusLost(); @@ -546,12 +518,6 @@ public static native void onNativeTouch(int touchDevId, int pointerFingerId, public static native void onNativeClipboardChanged(); public static native void onNativeSurfaceChanged(); public static native void onNativeSurfaceDestroyed(); - public static native int nativeAddJoystick(int device_id, String name, String desc, - int is_accelerometer, int nbuttons, - int naxes, int nhats, int nballs); - public static native int nativeRemoveJoystick(int device_id); - public static native int nativeAddHaptic(int device_id, String name); - public static native int nativeRemoveHaptic(int device_id); public static native String nativeGetHint(String name); /** @@ -632,7 +598,7 @@ public static boolean isScreenKeyboardShown() return false; } - InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE); + InputMethodManager imm = (InputMethodManager) SDL.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); if (imm.isAcceptingText()) { return true; } @@ -654,7 +620,7 @@ public static boolean sendMessage(int command, int param) { * This method is called by SDL using JNI. */ public static Context getContext() { - return mContext; + return SDL.getContext(); } static class ShowTextInputTask implements Runnable { @@ -681,7 +647,7 @@ public void run() { params.topMargin = y; if (mTextEdit == null) { - mTextEdit = new DummyEdit(getContext()); + mTextEdit = new DummyEdit(SDL.getContext()); mLayout.addView(mTextEdit, params); } else { @@ -691,7 +657,7 @@ public void run() { mTextEdit.setVisibility(View.VISIBLE); mTextEdit.requestFocus(); - InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE); + InputMethodManager imm = (InputMethodManager) SDL.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); imm.showSoftInput(mTextEdit, 0); mScreenKeyboardShown = true; @@ -731,156 +697,6 @@ public static Surface getNativeSurface() { return SDLActivity.mSurface.getNativeSurface(); } - // Audio - - /** - * This method is called by SDL using JNI. - */ - public static int audioOpen(int sampleRate, boolean is16Bit, boolean isStereo, int desiredFrames) { - int channelConfig = isStereo ? AudioFormat.CHANNEL_CONFIGURATION_STEREO : AudioFormat.CHANNEL_CONFIGURATION_MONO; - int audioFormat = is16Bit ? AudioFormat.ENCODING_PCM_16BIT : AudioFormat.ENCODING_PCM_8BIT; - int frameSize = (isStereo ? 2 : 1) * (is16Bit ? 2 : 1); - - Log.v(TAG, "SDL audio: wanted " + (isStereo ? "stereo" : "mono") + " " + (is16Bit ? "16-bit" : "8-bit") + " " + (sampleRate / 1000f) + "kHz, " + desiredFrames + " frames buffer"); - - // Let the user pick a larger buffer if they really want -- but ye - // gods they probably shouldn't, the minimums are horrifyingly high - // latency already - desiredFrames = Math.max(desiredFrames, (AudioTrack.getMinBufferSize(sampleRate, channelConfig, audioFormat) + frameSize - 1) / frameSize); - - if (mAudioTrack == null) { - mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate, - channelConfig, audioFormat, desiredFrames * frameSize, AudioTrack.MODE_STREAM); - - // Instantiating AudioTrack can "succeed" without an exception and the track may still be invalid - // Ref: https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/media/java/android/media/AudioTrack.java - // Ref: http://developer.android.com/reference/android/media/AudioTrack.html#getState() - - if (mAudioTrack.getState() != AudioTrack.STATE_INITIALIZED) { - Log.e(TAG, "Failed during initialization of Audio Track"); - mAudioTrack = null; - return -1; - } - - mAudioTrack.play(); - } - - Log.v(TAG, "SDL audio: got " + ((mAudioTrack.getChannelCount() >= 2) ? "stereo" : "mono") + " " + ((mAudioTrack.getAudioFormat() == AudioFormat.ENCODING_PCM_16BIT) ? "16-bit" : "8-bit") + " " + (mAudioTrack.getSampleRate() / 1000f) + "kHz, " + desiredFrames + " frames buffer"); - - return 0; - } - - /** - * This method is called by SDL using JNI. - */ - public static void audioWriteShortBuffer(short[] buffer) { - for (int i = 0; i < buffer.length; ) { - int result = mAudioTrack.write(buffer, i, buffer.length - i); - if (result > 0) { - i += result; - } else if (result == 0) { - try { - Thread.sleep(1); - } catch(InterruptedException e) { - // Nom nom - } - } else { - Log.w(TAG, "SDL audio: error return from write(short)"); - return; - } - } - } - - /** - * This method is called by SDL using JNI. - */ - public static void audioWriteByteBuffer(byte[] buffer) { - for (int i = 0; i < buffer.length; ) { - int result = mAudioTrack.write(buffer, i, buffer.length - i); - if (result > 0) { - i += result; - } else if (result == 0) { - try { - Thread.sleep(1); - } catch(InterruptedException e) { - // Nom nom - } - } else { - Log.w(TAG, "SDL audio: error return from write(byte)"); - return; - } - } - } - - /** - * This method is called by SDL using JNI. - */ - public static int captureOpen(int sampleRate, boolean is16Bit, boolean isStereo, int desiredFrames) { - int channelConfig = isStereo ? AudioFormat.CHANNEL_CONFIGURATION_STEREO : AudioFormat.CHANNEL_CONFIGURATION_MONO; - int audioFormat = is16Bit ? AudioFormat.ENCODING_PCM_16BIT : AudioFormat.ENCODING_PCM_8BIT; - int frameSize = (isStereo ? 2 : 1) * (is16Bit ? 2 : 1); - - Log.v(TAG, "SDL capture: wanted " + (isStereo ? "stereo" : "mono") + " " + (is16Bit ? "16-bit" : "8-bit") + " " + (sampleRate / 1000f) + "kHz, " + desiredFrames + " frames buffer"); - - // Let the user pick a larger buffer if they really want -- but ye - // gods they probably shouldn't, the minimums are horrifyingly high - // latency already - desiredFrames = Math.max(desiredFrames, (AudioRecord.getMinBufferSize(sampleRate, channelConfig, audioFormat) + frameSize - 1) / frameSize); - - if (mAudioRecord == null) { - mAudioRecord = new AudioRecord(MediaRecorder.AudioSource.DEFAULT, sampleRate, - channelConfig, audioFormat, desiredFrames * frameSize); - - // see notes about AudioTrack state in audioOpen(), above. Probably also applies here. - if (mAudioRecord.getState() != AudioRecord.STATE_INITIALIZED) { - Log.e(TAG, "Failed during initialization of AudioRecord"); - mAudioRecord.release(); - mAudioRecord = null; - return -1; - } - - mAudioRecord.startRecording(); - } - - Log.v(TAG, "SDL capture: got " + ((mAudioRecord.getChannelCount() >= 2) ? "stereo" : "mono") + " " + ((mAudioRecord.getAudioFormat() == AudioFormat.ENCODING_PCM_16BIT) ? "16-bit" : "8-bit") + " " + (mAudioRecord.getSampleRate() / 1000f) + "kHz, " + desiredFrames + " frames buffer"); - - return 0; - } - - /** This method is called by SDL using JNI. */ - public static int captureReadShortBuffer(short[] buffer, boolean blocking) { - // !!! FIXME: this is available in API Level 23. Until then, we always block. :( - //return mAudioRecord.read(buffer, 0, buffer.length, blocking ? AudioRecord.READ_BLOCKING : AudioRecord.READ_NON_BLOCKING); - return mAudioRecord.read(buffer, 0, buffer.length); - } - - /** This method is called by SDL using JNI. */ - public static int captureReadByteBuffer(byte[] buffer, boolean blocking) { - // !!! FIXME: this is available in API Level 23. Until then, we always block. :( - //return mAudioRecord.read(buffer, 0, buffer.length, blocking ? AudioRecord.READ_BLOCKING : AudioRecord.READ_NON_BLOCKING); - return mAudioRecord.read(buffer, 0, buffer.length); - } - - - /** This method is called by SDL using JNI. */ - public static void audioClose() { - if (mAudioTrack != null) { - mAudioTrack.stop(); - mAudioTrack.release(); - mAudioTrack = null; - } - } - - /** This method is called by SDL using JNI. */ - public static void captureClose() { - if (mAudioRecord != null) { - mAudioRecord.stop(); - mAudioRecord.release(); - mAudioRecord = null; - } - } - - // Input /** @@ -900,67 +716,20 @@ public static int[] inputGetInputDeviceIds(int sources) { return Arrays.copyOf(filtered, used); } - // Joystick glue code, just a series of stubs that redirect to the SDLJoystickHandler instance - public static boolean handleJoystickMotionEvent(MotionEvent event) { - return mJoystickHandler.handleMotionEvent(event); - } - - /** - * This method is called by SDL using JNI. - */ - public static void pollInputDevices() { - if (SDLActivity.mSDLThread != null) { - mJoystickHandler.pollInputDevices(); - } - } - - /** - * This method is called by SDL using JNI. - */ - public static void pollHapticDevices() { - if (SDLActivity.mSDLThread != null) { - mHapticHandler.pollHapticDevices(); - } - } - - /** - * This method is called by SDL using JNI. - */ - public static void hapticRun(int device_id, int length) { - if (SDLActivity.mSDLThread != null) { - mHapticHandler.run(device_id, length); - } - } - - // Check if a given device is considered a possible SDL joystick - public static boolean isDeviceSDLJoystick(int deviceId) { - InputDevice device = InputDevice.getDevice(deviceId); - // We cannot use InputDevice.isVirtual before API 16, so let's accept - // only nonnegative device ids (VIRTUAL_KEYBOARD equals -1) - if ((device == null) || (deviceId < 0)) { - return false; - } - int sources = device.getSources(); - return (((sources & InputDevice.SOURCE_CLASS_JOYSTICK) == InputDevice.SOURCE_CLASS_JOYSTICK) || - ((sources & InputDevice.SOURCE_DPAD) == InputDevice.SOURCE_DPAD) || - ((sources & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD) - ); - } - // APK expansion files support /** com.android.vending.expansion.zipfile.ZipResourceFile object or null. */ - private Object expansionFile; + private static Object expansionFile; /** com.android.vending.expansion.zipfile.ZipResourceFile's getInputStream() or null. */ - private Method expansionFileMethod; + private static Method expansionFileMethod; /** * This method is called by SDL using JNI. * @return an InputStream on success or null if no expansion file was used. * @throws IOException on errors. Message is set for the SDL error message. */ - public InputStream openAPKExpansionInputStream(String fileName) throws IOException { + public static InputStream openAPKExpansionInputStream(String fileName) throws IOException { // Get a ZipResourceFile representing a merger of both the main and patch files if (expansionFile == null) { String mainHint = nativeGetHint("SDL_ANDROID_APK_EXPANSION_MAIN_FILE_VERSION"); @@ -987,7 +756,7 @@ public InputStream openAPKExpansionInputStream(String fileName) throws IOExcepti // not a part of Android SDK we access it using reflection expansionFile = Class.forName("com.android.vending.expansion.zipfile.APKExpansionSupport") .getMethod("getAPKExpansionZipFile", Context.class, int.class, int.class) - .invoke(null, this, mainVersion, patchVersion); + .invoke(null, SDL.getContext(), mainVersion, patchVersion); expansionFileMethod = expansionFile.getClass() .getMethod("getInputStream", String.class); @@ -1452,14 +1221,14 @@ public boolean onKey(View v, int keyCode, KeyEvent event) { // Furthermore, it's possible a game controller has SOURCE_KEYBOARD and // SOURCE_JOYSTICK, while its key events arrive from the keyboard source // So, retrieve the device itself and check all of its sources - if (SDLActivity.isDeviceSDLJoystick(event.getDeviceId())) { + if (SDLControllerManager.isDeviceSDLJoystick(event.getDeviceId())) { // Note that we process events with specific key codes here if (event.getAction() == KeyEvent.ACTION_DOWN) { - if (SDLActivity.onNativePadDown(event.getDeviceId(), keyCode) == 0) { + if (SDLControllerManager.onNativePadDown(event.getDeviceId(), keyCode) == 0) { return true; } } else if (event.getAction() == KeyEvent.ACTION_UP) { - if (SDLActivity.onNativePadUp(event.getDeviceId(), keyCode) == 0) { + if (SDLControllerManager.onNativePadUp(event.getDeviceId(), keyCode) == 0) { return true; } } @@ -1759,331 +1528,6 @@ public boolean deleteSurroundingText(int beforeLength, int afterLength) { } } -/* A null joystick handler for API level < 12 devices (the accelerometer is handled separately) */ -class SDLJoystickHandler { - - /** - * Handles given MotionEvent. - * @param event the event to be handled. - * @return if given event was processed. - */ - public boolean handleMotionEvent(MotionEvent event) { - return false; - } - - /** - * Handles adding and removing of input devices. - */ - public void pollInputDevices() { - } -} - -/* Actual joystick functionality available for API >= 12 devices */ -class SDLJoystickHandler_API12 extends SDLJoystickHandler { - - static class SDLJoystick { - public int device_id; - public String name; - public String desc; - public ArrayList axes; - public ArrayList hats; - } - static class RangeComparator implements Comparator { - @Override - public int compare(InputDevice.MotionRange arg0, InputDevice.MotionRange arg1) { - return arg0.getAxis() - arg1.getAxis(); - } - } - - private ArrayList mJoysticks; - - public SDLJoystickHandler_API12() { - - mJoysticks = new ArrayList(); - } - - @Override - public void pollInputDevices() { - int[] deviceIds = InputDevice.getDeviceIds(); - // It helps processing the device ids in reverse order - // For example, in the case of the XBox 360 wireless dongle, - // so the first controller seen by SDL matches what the receiver - // considers to be the first controller - - for(int i=deviceIds.length-1; i>-1; i--) { - SDLJoystick joystick = getJoystick(deviceIds[i]); - if (joystick == null) { - joystick = new SDLJoystick(); - InputDevice joystickDevice = InputDevice.getDevice(deviceIds[i]); - if (SDLActivity.isDeviceSDLJoystick(deviceIds[i])) { - joystick.device_id = deviceIds[i]; - joystick.name = joystickDevice.getName(); - joystick.desc = getJoystickDescriptor(joystickDevice); - joystick.axes = new ArrayList(); - joystick.hats = new ArrayList(); - - List ranges = joystickDevice.getMotionRanges(); - Collections.sort(ranges, new RangeComparator()); - for (InputDevice.MotionRange range : ranges ) { - if ((range.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) { - if (range.getAxis() == MotionEvent.AXIS_HAT_X || - range.getAxis() == MotionEvent.AXIS_HAT_Y) { - joystick.hats.add(range); - } - else { - joystick.axes.add(range); - } - } - } - - mJoysticks.add(joystick); - SDLActivity.nativeAddJoystick(joystick.device_id, joystick.name, joystick.desc, 0, -1, - joystick.axes.size(), joystick.hats.size()/2, 0); - } - } - } - - /* Check removed devices */ - ArrayList removedDevices = new ArrayList(); - for(int i=0; i < mJoysticks.size(); i++) { - int device_id = mJoysticks.get(i).device_id; - int j; - for (j=0; j < deviceIds.length; j++) { - if (device_id == deviceIds[j]) break; - } - if (j == deviceIds.length) { - removedDevices.add(Integer.valueOf(device_id)); - } - } - - for(int i=0; i < removedDevices.size(); i++) { - int device_id = removedDevices.get(i).intValue(); - SDLActivity.nativeRemoveJoystick(device_id); - for (int j=0; j < mJoysticks.size(); j++) { - if (mJoysticks.get(j).device_id == device_id) { - mJoysticks.remove(j); - break; - } - } - } - } - - protected SDLJoystick getJoystick(int device_id) { - for(int i=0; i < mJoysticks.size(); i++) { - if (mJoysticks.get(i).device_id == device_id) { - return mJoysticks.get(i); - } - } - return null; - } - - @Override - public boolean handleMotionEvent(MotionEvent event) { - if ((event.getSource() & InputDevice.SOURCE_JOYSTICK) != 0) { - int actionPointerIndex = event.getActionIndex(); - int action = event.getActionMasked(); - switch(action) { - case MotionEvent.ACTION_MOVE: - SDLJoystick joystick = getJoystick(event.getDeviceId()); - if ( joystick != null ) { - for (int i = 0; i < joystick.axes.size(); i++) { - InputDevice.MotionRange range = joystick.axes.get(i); - /* Normalize the value to -1...1 */ - float value = ( event.getAxisValue( range.getAxis(), actionPointerIndex) - range.getMin() ) / range.getRange() * 2.0f - 1.0f; - SDLActivity.onNativeJoy(joystick.device_id, i, value ); - } - for (int i = 0; i < joystick.hats.size(); i+=2) { - int hatX = Math.round(event.getAxisValue( joystick.hats.get(i).getAxis(), actionPointerIndex ) ); - int hatY = Math.round(event.getAxisValue( joystick.hats.get(i+1).getAxis(), actionPointerIndex ) ); - SDLActivity.onNativeHat(joystick.device_id, i/2, hatX, hatY ); - } - } - break; - default: - break; - } - } - return true; - } - - public String getJoystickDescriptor(InputDevice joystickDevice) { - return joystickDevice.getName(); - } -} - - -class SDLJoystickHandler_API16 extends SDLJoystickHandler_API12 { - - @Override - public String getJoystickDescriptor(InputDevice joystickDevice) { - String desc = joystickDevice.getDescriptor(); - - if (desc != null && desc != "") { - return desc; - } - - return super.getJoystickDescriptor(joystickDevice); - } -} - -class SDLGenericMotionListener_API12 implements View.OnGenericMotionListener { - // Generic Motion (mouse hover, joystick...) events go here - @Override - public boolean onGenericMotion(View v, MotionEvent event) { - float x, y; - int action; - - switch ( event.getSource() ) { - case InputDevice.SOURCE_JOYSTICK: - case InputDevice.SOURCE_GAMEPAD: - case InputDevice.SOURCE_DPAD: - return SDLActivity.handleJoystickMotionEvent(event); - - case InputDevice.SOURCE_MOUSE: - if (!SDLActivity.mSeparateMouseAndTouch) { - break; - } - action = event.getActionMasked(); - switch (action) { - case MotionEvent.ACTION_SCROLL: - x = event.getAxisValue(MotionEvent.AXIS_HSCROLL, 0); - y = event.getAxisValue(MotionEvent.AXIS_VSCROLL, 0); - SDLActivity.onNativeMouse(0, action, x, y); - return true; - - case MotionEvent.ACTION_HOVER_MOVE: - x = event.getX(0); - y = event.getY(0); - - SDLActivity.onNativeMouse(0, action, x, y); - return true; - - default: - break; - } - break; - - default: - break; - } - - // Event was not managed - return false; - } -} - -class SDLHapticHandler { - - class SDLHaptic { - public int device_id; - public String name; - public Vibrator vib; - } - - private ArrayList mHaptics; - - public SDLHapticHandler() { - mHaptics = new ArrayList(); - } - - public void run(int device_id, int length) { - SDLHaptic haptic = getHaptic(device_id); - if (haptic != null) { - haptic.vib.vibrate (length); - } - } - - public void pollHapticDevices() { - - final int deviceId_VIBRATOR_SERVICE = 999999; - boolean hasVibratorService = false; - - int[] deviceIds = InputDevice.getDeviceIds(); - // It helps processing the device ids in reverse order - // For example, in the case of the XBox 360 wireless dongle, - // so the first controller seen by SDL matches what the receiver - // considers to be the first controller - - if (Build.VERSION.SDK_INT >= 16) - { - for (int i = deviceIds.length-1; i > -1; i--) { - SDLHaptic haptic = getHaptic(deviceIds[i]); - if (haptic == null) { - InputDevice device = InputDevice.getDevice(deviceIds[i]); - Vibrator vib = device.getVibrator(); - if (vib.hasVibrator()) { - haptic = new SDLHaptic(); - haptic.device_id = deviceIds[i]; - haptic.name = device.getName(); - haptic.vib = vib; - mHaptics.add(haptic); - SDLActivity.nativeAddHaptic(haptic.device_id, haptic.name); - } - } - } - } - - /* Check VIBRATOR_SERVICE */ - Vibrator vib = (Vibrator) SDLActivity.mSingleton.getContext().getSystemService(Context.VIBRATOR_SERVICE); - if (vib != null) { - if (Build.VERSION.SDK_INT >= 11) { - hasVibratorService = vib.hasVibrator(); - } else { - hasVibratorService = true; - } - - if (hasVibratorService) { - SDLHaptic haptic = getHaptic(deviceId_VIBRATOR_SERVICE); - if (haptic == null) { - haptic = new SDLHaptic(); - haptic.device_id = deviceId_VIBRATOR_SERVICE; - haptic.name = "VIBRATOR_SERVICE"; - haptic.vib = vib; - mHaptics.add(haptic); - SDLActivity.nativeAddHaptic(haptic.device_id, haptic.name); - } - } - } - - /* Check removed devices */ - ArrayList removedDevices = new ArrayList(); - for(int i=0; i < mHaptics.size(); i++) { - int device_id = mHaptics.get(i).device_id; - int j; - for (j=0; j < deviceIds.length; j++) { - if (device_id == deviceIds[j]) break; - } - - if (device_id == deviceId_VIBRATOR_SERVICE && hasVibratorService) { - // don't remove the vibrator if it is still present - } else if (j == deviceIds.length) { - removedDevices.add(device_id); - } - } - - for(int i=0; i < removedDevices.size(); i++) { - int device_id = removedDevices.get(i); - SDLActivity.nativeRemoveHaptic(device_id); - for (int j=0; j < mHaptics.size(); j++) { - if (mHaptics.get(j).device_id == device_id) { - mHaptics.remove(j); - break; - } - } - } - } - - protected SDLHaptic getHaptic(int device_id) { - for(int i=0; i < mHaptics.size(); i++) { - if (mHaptics.get(i).device_id == device_id) { - return mHaptics.get(i); - } - } - return null; - } -} - - interface SDLClipboardHandler { public boolean clipboardHasText(); @@ -2100,7 +1544,7 @@ class SDLClipboardHandler_API11 implements protected android.content.ClipboardManager mClipMgr; SDLClipboardHandler_API11() { - mClipMgr = (android.content.ClipboardManager) SDLActivity.mSingleton.getContext().getSystemService(Context.CLIPBOARD_SERVICE); + mClipMgr = (android.content.ClipboardManager) SDL.getContext().getSystemService(Context.CLIPBOARD_SERVICE); mClipMgr.addPrimaryClipChangedListener(this); } @@ -2139,7 +1583,7 @@ class SDLClipboardHandler_Old implements protected android.text.ClipboardManager mClipMgrOld; SDLClipboardHandler_Old() { - mClipMgrOld = (android.text.ClipboardManager) SDLActivity.mSingleton.getContext().getSystemService(Context.CLIPBOARD_SERVICE); + mClipMgrOld = (android.text.ClipboardManager) SDL.getContext().getSystemService(Context.CLIPBOARD_SERVICE); } @Override @@ -2164,4 +1608,3 @@ public void clipboardSetText(String string) { } } - diff --git a/src/core/android/SDL_android.c b/src/core/android/SDL_android.c index a7f4e52fbb..48cf7b7962 100644 --- a/src/core/android/SDL_android.c +++ b/src/core/android/SDL_android.c @@ -56,6 +56,8 @@ #define CONCAT1(prefix, class, function) CONCAT2(prefix, class, function) #define CONCAT2(prefix, class, function) Java_ ## prefix ## _ ## class ## _ ## function #define SDL_JAVA_INTERFACE(function) CONCAT1(SDL_JAVA_PREFIX, SDLActivity, function) +#define SDL_JAVA_AUDIO_INTERFACE(function) CONCAT1(SDL_JAVA_PREFIX, SDLAudioManager, function) +#define SDL_JAVA_CONTROLLER_INTERFACE(function) CONCAT1(SDL_JAVA_PREFIX, SDLControllerManager, function) #define SDL_JAVA_INTERFACE_INPUT_CONNECTION(function) CONCAT1(SDL_JAVA_PREFIX, SDLInputConnection, function) @@ -75,39 +77,6 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeResize)( JNIEnv* env, jclass jcls, jint width, jint height, jint format, jfloat rate); -JNIEXPORT jint JNICALL SDL_JAVA_INTERFACE(onNativePadDown)( - JNIEnv* env, jclass jcls, - jint device_id, jint keycode); - -JNIEXPORT jint JNICALL SDL_JAVA_INTERFACE(onNativePadUp)( - JNIEnv* env, jclass jcls, - jint device_id, jint keycode); - -JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeJoy)( - JNIEnv* env, jclass jcls, - jint device_id, jint axis, jfloat value); - -JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeHat)( - JNIEnv* env, jclass jcls, - jint device_id, jint hat_id, jint x, jint y); - -JNIEXPORT jint JNICALL SDL_JAVA_INTERFACE(nativeAddJoystick)( - JNIEnv* env, jclass jcls, - jint device_id, jstring device_name, jstring device_desc, jint is_accelerometer, - jint nbuttons, jint naxes, jint nhats, jint nballs); - -JNIEXPORT jint JNICALL SDL_JAVA_INTERFACE(nativeRemoveJoystick)( - JNIEnv* env, jclass jcls, - jint device_id); - -JNIEXPORT jint JNICALL SDL_JAVA_INTERFACE(nativeAddHaptic)( - JNIEnv* env, jclass jcls, - jint device_id, jstring device_name); - -JNIEXPORT jint JNICALL SDL_JAVA_INTERFACE(nativeRemoveHaptic)( - JNIEnv* env, jclass jcls, - jint device_id); - JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeSurfaceChanged)( JNIEnv* env, jclass jcls); @@ -166,6 +135,48 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeSetComposingTex JNIEnv* env, jclass cls, jstring text, jint newCursorPosition); +/* Java class SDLAudioManager */ +JNIEXPORT void JNICALL SDL_JAVA_AUDIO_INTERFACE(nativeSetupJNI)( + JNIEnv *env, jclass jcls); + +/* Java class SDLControllerManager */ +JNIEXPORT void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeSetupJNI)( + JNIEnv *env, jclass jcls); + +JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativePadDown)( + JNIEnv* env, jclass jcls, + jint device_id, jint keycode); + +JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativePadUp)( + JNIEnv* env, jclass jcls, + jint device_id, jint keycode); + +JNIEXPORT void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativeJoy)( + JNIEnv* env, jclass jcls, + jint device_id, jint axis, jfloat value); + +JNIEXPORT void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativeHat)( + JNIEnv* env, jclass jcls, + jint device_id, jint hat_id, jint x, jint y); + +JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeAddJoystick)( + JNIEnv* env, jclass jcls, + jint device_id, jstring device_name, jstring device_desc, jint is_accelerometer, + jint nbuttons, jint naxes, jint nhats, jint nballs); + +JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeRemoveJoystick)( + JNIEnv* env, jclass jcls, + jint device_id); + +JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeAddHaptic)( + JNIEnv* env, jclass jcls, + jint device_id, jstring device_name); + +JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeRemoveHaptic)( + JNIEnv* env, jclass jcls, + jint device_id); + + /* Uncomment this to log messages entering and exiting methods in this file */ /* #define DEBUG_JNI */ @@ -189,17 +200,6 @@ static jclass mActivityClass; /* method signatures */ static jmethodID midGetNativeSurface; -static jmethodID midAudioOpen; -static jmethodID midAudioWriteShortBuffer; -static jmethodID midAudioWriteByteBuffer; -static jmethodID midAudioClose; -static jmethodID midCaptureOpen; -static jmethodID midCaptureReadShortBuffer; -static jmethodID midCaptureReadByteBuffer; -static jmethodID midCaptureClose; -static jmethodID midPollInputDevices; -static jmethodID midPollHapticDevices; -static jmethodID midHapticRun; static jmethodID midSetActivityTitle; static jmethodID midSetOrientation; static jmethodID midGetContext; @@ -210,7 +210,28 @@ static jmethodID midIsScreenKeyboardShown; static jmethodID midClipboardSetText; static jmethodID midClipboardGetText; static jmethodID midClipboardHasText; +static jmethodID midOpenAPKExpansionInputStream; +/* audio manager */ +static jclass mAudioManagerClass; + +/* method signatures */ +static jmethodID midAudioOpen; +static jmethodID midAudioWriteShortBuffer; +static jmethodID midAudioWriteByteBuffer; +static jmethodID midAudioClose; +static jmethodID midCaptureOpen; +static jmethodID midCaptureReadShortBuffer; +static jmethodID midCaptureReadByteBuffer; +static jmethodID midCaptureClose; + +/* controller manager */ +static jclass mControllerManagerClass; + +/* method signatures */ +static jmethodID midPollInputDevices; +static jmethodID midPollHapticDevices; +static jmethodID midHapticRun; /* static fields */ static jfieldID fidSeparateMouseAndTouch; @@ -245,7 +266,17 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) return JNI_VERSION_1_4; } -/* Called before SDL_main() to initialize JNI bindings */ +void checkJNIReady() +{ + if (!mActivityClass || !mAudioManagerClass || !mControllerManagerClass) { + // We aren't fully initialized, let's just return. + return; + } + + SDL_SetMainReady(); +} + +/* Activity initialization -- called before SDL_main() to initialize JNI bindings */ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(JNIEnv* mEnv, jclass cls) { __android_log_print(ANDROID_LOG_VERBOSE, "SDL", "nativeSetupJNI()"); @@ -256,28 +287,6 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(JNIEnv* mEnv, jclass c midGetNativeSurface = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, "getNativeSurface","()Landroid/view/Surface;"); - midAudioOpen = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, - "audioOpen", "(IZZI)I"); - midAudioWriteShortBuffer = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, - "audioWriteShortBuffer", "([S)V"); - midAudioWriteByteBuffer = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, - "audioWriteByteBuffer", "([B)V"); - midAudioClose = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, - "audioClose", "()V"); - midCaptureOpen = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, - "captureOpen", "(IZZI)I"); - midCaptureReadShortBuffer = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, - "captureReadShortBuffer", "([SZ)I"); - midCaptureReadByteBuffer = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, - "captureReadByteBuffer", "([BZ)I"); - midCaptureClose = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, - "captureClose", "()V"); - midPollInputDevices = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, - "pollInputDevices", "()V"); - midPollHapticDevices = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, - "pollHapticDevices", "()V"); - midHapticRun = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, - "hapticRun", "(II)V"); midSetActivityTitle = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, "setActivityTitle","(Ljava/lang/String;)Z"); midSetOrientation = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, @@ -298,16 +307,14 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(JNIEnv* mEnv, jclass c "clipboardGetText", "()Ljava/lang/String;"); midClipboardHasText = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, "clipboardHasText", "()Z"); - - bHasNewData = SDL_FALSE; + midOpenAPKExpansionInputStream = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, + "openAPKExpansionInputStream", "(Ljava/lang/String;)Ljava/io/InputStream;"); if (!midGetNativeSurface || - !midAudioOpen || !midAudioWriteShortBuffer || !midAudioWriteByteBuffer || !midAudioClose || - !midCaptureOpen || !midCaptureReadShortBuffer || !midCaptureReadByteBuffer || !midCaptureClose || - !midPollInputDevices || !midPollHapticDevices || !midHapticRun || !midSetActivityTitle || !midSetOrientation || !midGetContext || !midInputGetInputDeviceIds || !midSendMessage || !midShowTextInput || !midIsScreenKeyboardShown || - !midClipboardSetText || !midClipboardGetText || !midClipboardHasText) { + !midClipboardSetText || !midClipboardGetText || !midClipboardHasText || + !midOpenAPKExpansionInputStream) { __android_log_print(ANDROID_LOG_WARN, "SDL", "Missing some Java callbacks, do you have the latest version of SDLActivity.java?"); } @@ -317,7 +324,64 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(JNIEnv* mEnv, jclass c __android_log_print(ANDROID_LOG_WARN, "SDL", "Missing some Java static fields, do you have the latest version of SDLActivity.java?"); } - SDL_SetMainReady(); + checkJNIReady(); +} + +/* Audio initialization -- called before SDL_main() to initialize JNI bindings */ +JNIEXPORT void JNICALL SDL_JAVA_AUDIO_INTERFACE(nativeSetupJNI)(JNIEnv* mEnv, jclass cls) +{ + __android_log_print(ANDROID_LOG_VERBOSE, "SDL", "AUDIO nativeSetupJNI()"); + + Android_JNI_SetupThread(); + + mAudioManagerClass = (jclass)((*mEnv)->NewGlobalRef(mEnv, cls)); + + midAudioOpen = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass, + "audioOpen", "(IZZI)I"); + midAudioWriteShortBuffer = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass, + "audioWriteShortBuffer", "([S)V"); + midAudioWriteByteBuffer = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass, + "audioWriteByteBuffer", "([B)V"); + midAudioClose = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass, + "audioClose", "()V"); + midCaptureOpen = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass, + "captureOpen", "(IZZI)I"); + midCaptureReadShortBuffer = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass, + "captureReadShortBuffer", "([SZ)I"); + midCaptureReadByteBuffer = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass, + "captureReadByteBuffer", "([BZ)I"); + midCaptureClose = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass, + "captureClose", "()V"); + + if (!midAudioOpen || !midAudioWriteShortBuffer || !midAudioWriteByteBuffer || !midAudioClose || + !midCaptureOpen || !midCaptureReadShortBuffer || !midCaptureReadByteBuffer || !midCaptureClose) { + __android_log_print(ANDROID_LOG_WARN, "SDL", "Missing some Java callbacks, do you have the latest version of SDLAudioManager.java?"); + } + + checkJNIReady(); +} + +/* Controller initialization -- called before SDL_main() to initialize JNI bindings */ +JNIEXPORT void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeSetupJNI)(JNIEnv* mEnv, jclass cls) +{ + __android_log_print(ANDROID_LOG_VERBOSE, "SDL", "CONTROLLER nativeSetupJNI()"); + + Android_JNI_SetupThread(); + + mControllerManagerClass = (jclass)((*mEnv)->NewGlobalRef(mEnv, cls)); + + midPollInputDevices = (*mEnv)->GetStaticMethodID(mEnv, mControllerManagerClass, + "pollInputDevices", "()V"); + midPollHapticDevices = (*mEnv)->GetStaticMethodID(mEnv, mControllerManagerClass, + "pollHapticDevices", "()V"); + midHapticRun = (*mEnv)->GetStaticMethodID(mEnv, mControllerManagerClass, + "hapticRun", "(II)V"); + + if (!midPollInputDevices || !midPollHapticDevices || !midHapticRun) { + __android_log_print(ANDROID_LOG_WARN, "SDL", "Missing some Java callbacks, do you have the latest version of SDLControllerManager.java?"); + } + + checkJNIReady(); } /* SDL main function prototype */ @@ -421,7 +485,7 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeResize)( } /* Paddown */ -JNIEXPORT jint JNICALL SDL_JAVA_INTERFACE(onNativePadDown)( +JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativePadDown)( JNIEnv* env, jclass jcls, jint device_id, jint keycode) { @@ -429,7 +493,7 @@ JNIEXPORT jint JNICALL SDL_JAVA_INTERFACE(onNativePadDown)( } /* Padup */ -JNIEXPORT jint JNICALL SDL_JAVA_INTERFACE(onNativePadUp)( +JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativePadUp)( JNIEnv* env, jclass jcls, jint device_id, jint keycode) { @@ -437,7 +501,7 @@ JNIEXPORT jint JNICALL SDL_JAVA_INTERFACE(onNativePadUp)( } /* Joy */ -JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeJoy)( +JNIEXPORT void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativeJoy)( JNIEnv* env, jclass jcls, jint device_id, jint axis, jfloat value) { @@ -445,7 +509,7 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeJoy)( } /* POV Hat */ -JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeHat)( +JNIEXPORT void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativeHat)( JNIEnv* env, jclass jcls, jint device_id, jint hat_id, jint x, jint y) { @@ -453,7 +517,7 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeHat)( } -JNIEXPORT jint JNICALL SDL_JAVA_INTERFACE(nativeAddJoystick)( +JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeAddJoystick)( JNIEnv* env, jclass jcls, jint device_id, jstring device_name, jstring device_desc, jint is_accelerometer, jint nbuttons, jint naxes, jint nhats, jint nballs) @@ -470,14 +534,14 @@ JNIEXPORT jint JNICALL SDL_JAVA_INTERFACE(nativeAddJoystick)( return retval; } -JNIEXPORT jint JNICALL SDL_JAVA_INTERFACE(nativeRemoveJoystick)( +JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeRemoveJoystick)( JNIEnv* env, jclass jcls, jint device_id) { return Android_RemoveJoystick(device_id); } -JNIEXPORT jint JNICALL SDL_JAVA_INTERFACE(nativeAddHaptic)( +JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeAddHaptic)( JNIEnv* env, jclass jcls, jint device_id, jstring device_name) { int retval; @@ -490,7 +554,7 @@ JNIEXPORT jint JNICALL SDL_JAVA_INTERFACE(nativeAddHaptic)( return retval; } -JNIEXPORT jint JNICALL SDL_JAVA_INTERFACE(nativeRemoveHaptic)( +JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeRemoveHaptic)( JNIEnv* env, jclass jcls, jint device_id) { return Android_RemoveHaptic(device_id); @@ -882,7 +946,7 @@ int Android_JNI_OpenAudioDevice(int iscapture, int sampleRate, int is16Bit, int if (iscapture) { __android_log_print(ANDROID_LOG_VERBOSE, "SDL", "SDL audio: opening device for capture"); captureBuffer16Bit = is16Bit; - if ((*env)->CallStaticIntMethod(env, mActivityClass, midCaptureOpen, sampleRate, audioBuffer16Bit, audioBufferStereo, desiredBufferFrames) != 0) { + if ((*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureOpen, sampleRate, audioBuffer16Bit, audioBufferStereo, desiredBufferFrames) != 0) { /* Error during audio initialization */ __android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: error on AudioRecord initialization!"); return 0; @@ -890,7 +954,7 @@ int Android_JNI_OpenAudioDevice(int iscapture, int sampleRate, int is16Bit, int } else { __android_log_print(ANDROID_LOG_VERBOSE, "SDL", "SDL audio: opening device for output"); audioBuffer16Bit = is16Bit; - if ((*env)->CallStaticIntMethod(env, mActivityClass, midAudioOpen, sampleRate, audioBuffer16Bit, audioBufferStereo, desiredBufferFrames) != 0) { + if ((*env)->CallStaticIntMethod(env, mAudioManagerClass, midAudioOpen, sampleRate, audioBuffer16Bit, audioBufferStereo, desiredBufferFrames) != 0) { /* Error during audio initialization */ __android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: error on AudioTrack initialization!"); return 0; @@ -958,10 +1022,10 @@ void Android_JNI_WriteAudioBuffer(void) if (audioBuffer16Bit) { (*mAudioEnv)->ReleaseShortArrayElements(mAudioEnv, (jshortArray)audioBuffer, (jshort *)audioBufferPinned, JNI_COMMIT); - (*mAudioEnv)->CallStaticVoidMethod(mAudioEnv, mActivityClass, midAudioWriteShortBuffer, (jshortArray)audioBuffer); + (*mAudioEnv)->CallStaticVoidMethod(mAudioEnv, mAudioManagerClass, midAudioWriteShortBuffer, (jshortArray)audioBuffer); } else { (*mAudioEnv)->ReleaseByteArrayElements(mAudioEnv, (jbyteArray)audioBuffer, (jbyte *)audioBufferPinned, JNI_COMMIT); - (*mAudioEnv)->CallStaticVoidMethod(mAudioEnv, mActivityClass, midAudioWriteByteBuffer, (jbyteArray)audioBuffer); + (*mAudioEnv)->CallStaticVoidMethod(mAudioEnv, mAudioManagerClass, midAudioWriteByteBuffer, (jbyteArray)audioBuffer); } /* JNI_COMMIT means the changes are committed to the VM but the buffer remains pinned */ @@ -975,7 +1039,7 @@ int Android_JNI_CaptureAudioBuffer(void *buffer, int buflen) if (captureBuffer16Bit) { SDL_assert((*env)->GetArrayLength(env, (jshortArray)captureBuffer) == (buflen / 2)); - br = (*env)->CallStaticIntMethod(env, mActivityClass, midCaptureReadShortBuffer, (jshortArray)captureBuffer, JNI_TRUE); + br = (*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadShortBuffer, (jshortArray)captureBuffer, JNI_TRUE); if (br > 0) { jshort *ptr = (*env)->GetShortArrayElements(env, (jshortArray)captureBuffer, &isCopy); br *= 2; @@ -984,7 +1048,7 @@ int Android_JNI_CaptureAudioBuffer(void *buffer, int buflen) } } else { SDL_assert((*env)->GetArrayLength(env, (jshortArray)captureBuffer) == buflen); - br = (*env)->CallStaticIntMethod(env, mActivityClass, midCaptureReadByteBuffer, (jbyteArray)captureBuffer, JNI_TRUE); + br = (*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadByteBuffer, (jbyteArray)captureBuffer, JNI_TRUE); if (br > 0) { jbyte *ptr = (*env)->GetByteArrayElements(env, (jbyteArray)captureBuffer, &isCopy); SDL_memcpy(buffer, ptr, br); @@ -1008,9 +1072,9 @@ void Android_JNI_FlushCapturedAudio(void) } #else if (captureBuffer16Bit) { - (*env)->CallStaticIntMethod(env, mActivityClass, midCaptureReadShortBuffer, (jshortArray)captureBuffer, JNI_FALSE); + (*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadShortBuffer, (jshortArray)captureBuffer, JNI_FALSE); } else { - (*env)->CallStaticIntMethod(env, mActivityClass, midCaptureReadByteBuffer, (jbyteArray)captureBuffer, JNI_FALSE); + (*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadByteBuffer, (jbyteArray)captureBuffer, JNI_FALSE); } #endif } @@ -1020,13 +1084,13 @@ void Android_JNI_CloseAudioDevice(const int iscapture) JNIEnv *env = Android_JNI_GetEnv(); if (iscapture) { - (*env)->CallStaticVoidMethod(env, mActivityClass, midCaptureClose); + (*env)->CallStaticVoidMethod(env, mAudioManagerClass, midCaptureClose); if (captureBuffer) { (*env)->DeleteGlobalRef(env, captureBuffer); captureBuffer = NULL; } } else { - (*env)->CallStaticVoidMethod(env, mActivityClass, midAudioClose); + (*env)->CallStaticVoidMethod(env, mAudioManagerClass, midAudioClose); if (audioBuffer) { (*env)->DeleteGlobalRef(env, audioBuffer); audioBuffer = NULL; @@ -1160,13 +1224,7 @@ static int Internal_Android_JNI_FileOpen(SDL_RWops* ctx) inputStream = (*mEnv)->CallObjectMethod(mEnv, assetManager, mid, fileNameJString, 1 /* ACCESS_RANDOM */); if (Android_JNI_ExceptionOccurred(SDL_FALSE)) { /* Try fallback to APK expansion files */ - mid = (*mEnv)->GetMethodID(mEnv, (*mEnv)->GetObjectClass(mEnv, context), - "openAPKExpansionInputStream", "(Ljava/lang/String;)Ljava/io/InputStream;"); - if (!mid) { - SDL_SetError("No openAPKExpansionInputStream() in Java class"); - goto failure; /* Java class is missing the required method */ - } - inputStream = (*mEnv)->CallObjectMethod(mEnv, context, mid, fileNameJString); + inputStream = (*mEnv)->CallStaticObjectMethod(mEnv, mActivityClass, midOpenAPKExpansionInputStream, fileNameJString); /* Exception is checked first because it always needs to be cleared. * If no exception occurred then the last SDL error message is kept. @@ -1673,19 +1731,19 @@ void Android_JNI_SetSeparateMouseAndTouch(SDL_bool new_value) void Android_JNI_PollInputDevices(void) { JNIEnv *env = Android_JNI_GetEnv(); - (*env)->CallStaticVoidMethod(env, mActivityClass, midPollInputDevices); + (*env)->CallStaticVoidMethod(env, mControllerManagerClass, midPollInputDevices); } void Android_JNI_PollHapticDevices(void) { JNIEnv *env = Android_JNI_GetEnv(); - (*env)->CallStaticVoidMethod(env, mActivityClass, midPollHapticDevices); + (*env)->CallStaticVoidMethod(env, mControllerManagerClass, midPollHapticDevices); } void Android_JNI_HapticRun(int device_id, int length) { JNIEnv *env = Android_JNI_GetEnv(); - (*env)->CallStaticVoidMethod(env, mActivityClass, midHapticRun, device_id, length); + (*env)->CallStaticVoidMethod(env, mControllerManagerClass, midHapticRun, device_id, length); } @@ -1862,6 +1920,11 @@ const char * SDL_AndroidGetInternalStoragePath(void) /* context = SDLActivity.getContext(); */ context = (*env)->CallStaticObjectMethod(env, mActivityClass, midGetContext); + if (!context) { + SDL_SetError("Couldn't get Android context!"); + LocalReferenceHolder_Cleanup(&refs); + return NULL; + } /* fileObj = context.getFilesDir(); */ mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, context), From 1da7ce46c0351edfc702cb5f2a94d4d40ccba0ca Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 22 Sep 2017 08:30:52 -0700 Subject: [PATCH 07/95] Added stubs for simple Steam Controller support --- Android.mk | 6 +- Xcode-iOS/SDL/SDL.xcodeproj/project.pbxproj | 16 +++ configure | 2 + configure.in | 2 + src/joystick/SDL_gamecontroller.c | 27 ++++ src/joystick/SDL_gamecontrollerdb.h | 13 +- src/joystick/android/SDL_sysjoystick.c | 144 +++++++++++++++---- src/joystick/android/SDL_sysjoystick_c.h | 3 + src/joystick/iphoneos/SDL_sysjoystick.m | 60 +++++++- src/joystick/iphoneos/SDL_sysjoystick_c.h | 3 + src/joystick/linux/SDL_sysjoystick.c | 148 ++++++++++++++++---- src/joystick/linux/SDL_sysjoystick_c.h | 3 + src/joystick/steam/SDL_steamcontroller.c | 52 +++++++ 13 files changed, 422 insertions(+), 57 deletions(-) create mode 100644 src/joystick/steam/SDL_steamcontroller.c diff --git a/Android.mk b/Android.mk index 5c362ceba4..ac770d9036 100755 --- a/Android.mk +++ b/Android.mk @@ -31,6 +31,8 @@ LOCAL_SRC_FILES := \ $(wildcard $(LOCAL_PATH)/src/haptic/android/*.c) \ $(wildcard $(LOCAL_PATH)/src/joystick/*.c) \ $(wildcard $(LOCAL_PATH)/src/joystick/android/*.c) \ + $(LOCAL_PATH)/src/joystick/steam/SDL_steamcontroller.c \ + $(LOCAL_PATH)/src/joystick/steam/steamcontroller_hidapi.c \ $(wildcard $(LOCAL_PATH)/src/loadso/dlopen/*.c) \ $(wildcard $(LOCAL_PATH)/src/power/*.c) \ $(wildcard $(LOCAL_PATH)/src/power/android/*.c) \ @@ -44,7 +46,9 @@ LOCAL_SRC_FILES := \ $(wildcard $(LOCAL_PATH)/src/timer/unix/*.c) \ $(wildcard $(LOCAL_PATH)/src/video/*.c) \ $(wildcard $(LOCAL_PATH)/src/video/android/*.c) \ - $(wildcard $(LOCAL_PATH)/src/test/*.c)) + $(wildcard $(LOCAL_PATH)/src/test/*.c)) \ + +LOCAL_SHARED_LIBRARIES := hidapi LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES LOCAL_LDLIBS := -ldl -lGLESv1_CM -lGLESv2 -llog -landroid diff --git a/Xcode-iOS/SDL/SDL.xcodeproj/project.pbxproj b/Xcode-iOS/SDL/SDL.xcodeproj/project.pbxproj index efa00372c4..e7842c664c 100755 --- a/Xcode-iOS/SDL/SDL.xcodeproj/project.pbxproj +++ b/Xcode-iOS/SDL/SDL.xcodeproj/project.pbxproj @@ -90,6 +90,8 @@ 56F9D5601DF73BA400C15B5D /* SDL_dataqueue.c in Sources */ = {isa = PBXBuildFile; fileRef = 566726431DF72CF5001DD3DB /* SDL_dataqueue.c */; }; 93CB792313FC5E5200BD3E05 /* SDL_uikitviewcontroller.h in Headers */ = {isa = PBXBuildFile; fileRef = 93CB792213FC5E5200BD3E05 /* SDL_uikitviewcontroller.h */; }; 93CB792613FC5F5300BD3E05 /* SDL_uikitviewcontroller.m in Sources */ = {isa = PBXBuildFile; fileRef = 93CB792513FC5F5300BD3E05 /* SDL_uikitviewcontroller.m */; }; + A7A9EEA91F702631002A5589 /* SDL_steamcontroller.c in Sources */ = {isa = PBXBuildFile; fileRef = A7A9EEA71F702631002A5589 /* SDL_steamcontroller.c */; }; + A7A9EEAA1F702631002A5589 /* SDL_steamcontroller.h in Headers */ = {isa = PBXBuildFile; fileRef = A7A9EEA81F702631002A5589 /* SDL_steamcontroller.h */; }; AA0AD06216647BBB00CE5896 /* SDL_gamecontroller.c in Sources */ = {isa = PBXBuildFile; fileRef = AA0AD06116647BBB00CE5896 /* SDL_gamecontroller.c */; }; AA0AD06516647BD400CE5896 /* SDL_gamecontroller.h in Headers */ = {isa = PBXBuildFile; fileRef = AA0AD06416647BD400CE5896 /* SDL_gamecontroller.h */; }; AA0F8495178D5F1A00823F9D /* SDL_systls.c in Sources */ = {isa = PBXBuildFile; fileRef = AA0F8494178D5F1A00823F9D /* SDL_systls.c */; }; @@ -393,6 +395,8 @@ 56ED04E2118A8EFD00A56AA6 /* SDL_syspower.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SDL_syspower.m; path = ../../src/power/uikit/SDL_syspower.m; sourceTree = SOURCE_ROOT; }; 93CB792213FC5E5200BD3E05 /* SDL_uikitviewcontroller.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_uikitviewcontroller.h; sourceTree = ""; }; 93CB792513FC5F5300BD3E05 /* SDL_uikitviewcontroller.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDL_uikitviewcontroller.m; sourceTree = ""; }; + A7A9EEA71F702631002A5589 /* SDL_steamcontroller.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_steamcontroller.c; sourceTree = ""; }; + A7A9EEA81F702631002A5589 /* SDL_steamcontroller.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_steamcontroller.h; sourceTree = ""; }; AA0AD06116647BBB00CE5896 /* SDL_gamecontroller.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_gamecontroller.c; sourceTree = ""; }; AA0AD06416647BD400CE5896 /* SDL_gamecontroller.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_gamecontroller.h; sourceTree = ""; }; AA0F8494178D5F1A00823F9D /* SDL_systls.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_systls.c; sourceTree = ""; }; @@ -725,6 +729,15 @@ name = uikit; sourceTree = ""; }; + A7A9EEA61F702607002A5589 /* steam */ = { + isa = PBXGroup; + children = ( + A7A9EEA71F702631002A5589 /* SDL_steamcontroller.c */, + A7A9EEA81F702631002A5589 /* SDL_steamcontroller.h */, + ); + path = steam; + sourceTree = ""; + }; FD3F4A6F0DEA620800C5B771 /* stdlib */ = { isa = PBXGroup; children = ( @@ -742,6 +755,7 @@ FD5F9D080E0E08B3008E885B /* joystick */ = { isa = PBXGroup; children = ( + A7A9EEA61F702607002A5589 /* steam */, FD689EFF0E26E5B600F90B21 /* iphoneos */, AA0AD06116647BBB00CE5896 /* SDL_gamecontroller.c */, FD5F9D1E0E0E08B3008E885B /* SDL_joystick.c */, @@ -1124,6 +1138,7 @@ 04F7807E12FB751400FC43C0 /* SDL_drawline.h in Headers */, 04F7808012FB751400FC43C0 /* SDL_drawpoint.h in Headers */, 04F7808412FB753F00FC43C0 /* SDL_nullframebuffer_c.h in Headers */, + A7A9EEAA1F702631002A5589 /* SDL_steamcontroller.h in Headers */, 0442EC5012FE1C1E004C9285 /* SDL_render_sw_c.h in Headers */, FA1DC2721C62BE65008F99A0 /* SDL_uikitclipboard.h in Headers */, 0402A85A12FE70C600CECEE3 /* SDL_shaders_gles2.h in Headers */, @@ -1398,6 +1413,7 @@ files = ( FD6526810DE8FCDD002AD96B /* SDL_systimer.c in Sources */, FD6526800DE8FCDD002AD96B /* SDL_timer.c in Sources */, + A7A9EEA91F702631002A5589 /* SDL_steamcontroller.c in Sources */, FD3F4A7B0DEA620800C5B771 /* SDL_string.c in Sources */, FD6526660DE8FCDD002AD96B /* SDL_dummyaudio.c in Sources */, FD6526670DE8FCDD002AD96B /* SDL_audio.c in Sources */, diff --git a/configure b/configure index 14623c8cb5..53a5af427f 100755 --- a/configure +++ b/configure @@ -16846,6 +16846,7 @@ fi SOURCES="$SOURCES $srcdir/src/*.c" SOURCES="$SOURCES $srcdir/src/atomic/*.c" SOURCES="$SOURCES $srcdir/src/audio/*.c" +SOURCES="$SOURCES $srcdir/src/audio/marvell/*.c" SOURCES="$SOURCES $srcdir/src/cpuinfo/*.c" SOURCES="$SOURCES $srcdir/src/dynapi/*.c" SOURCES="$SOURCES $srcdir/src/events/*.c" @@ -23839,6 +23840,7 @@ $as_echo "#define SDL_AUDIO_DRIVER_ANDROID 1" >>confdefs.h $as_echo "#define SDL_JOYSTICK_LINUX 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/joystick/linux/*.c" + SOURCES="$SOURCES $srcdir/src/joystick/steam/*.c" have_joystick=yes ;; android) diff --git a/configure.in b/configure.in index e91851e288..759ba363e3 100644 --- a/configure.in +++ b/configure.in @@ -325,6 +325,7 @@ fi SOURCES="$SOURCES $srcdir/src/*.c" SOURCES="$SOURCES $srcdir/src/atomic/*.c" SOURCES="$SOURCES $srcdir/src/audio/*.c" +SOURCES="$SOURCES $srcdir/src/audio/marvell/*.c" SOURCES="$SOURCES $srcdir/src/cpuinfo/*.c" SOURCES="$SOURCES $srcdir/src/dynapi/*.c" SOURCES="$SOURCES $srcdir/src/events/*.c" @@ -3360,6 +3361,7 @@ case "$host" in linux) AC_DEFINE(SDL_JOYSTICK_LINUX, 1, [ ]) SOURCES="$SOURCES $srcdir/src/joystick/linux/*.c" + SOURCES="$SOURCES $srcdir/src/joystick/steam/*.c" have_joystick=yes ;; android) diff --git a/src/joystick/SDL_gamecontroller.c b/src/joystick/SDL_gamecontroller.c index 575593a4be..1483c98a85 100644 --- a/src/joystick/SDL_gamecontroller.c +++ b/src/joystick/SDL_gamecontroller.c @@ -33,6 +33,11 @@ #include "../events/SDL_events_c.h" #endif +#if defined(__ANDROID__) +#include "SDL_system.h" +#endif + + #define SDL_CONTROLLER_PLATFORM_FIELD "platform:" /* a list of currently opened game controllers */ @@ -1157,12 +1162,30 @@ SDL_GameControllerLoadHints() } } +/* + * Fill the given buffer with the expected controller mapping filepath. + * Usually this will just be CONTROLLER_MAPPING_FILE, but for Android, + * we want to get the internal storage path. + */ +static SDL_bool SDL_GetControllerMappingFilePath(char *path, size_t size) +{ +#ifdef CONTROLLER_MAPPING_FILE +#define STRING(X) SDL_STRINGIFY_ARG(X) + return SDL_strlcpy(path, STRING(CONTROLLER_MAPPING_FILE), size) < size; +#elif defined(__ANDROID__) + return SDL_snprintf(path, size, "%s/controller_map.txt", SDL_AndroidGetInternalStoragePath()) < size; +#else + return SDL_FALSE; +#endif +} + /* * Initialize the game controller system, mostly load our DB of controller config mappings */ int SDL_GameControllerInitMappings(void) { + char szControllerMapPath[1024]; int i = 0; const char *pMappingString = NULL; pMappingString = s_ControllerMappings[i]; @@ -1173,6 +1196,10 @@ SDL_GameControllerInitMappings(void) pMappingString = s_ControllerMappings[i]; } + if (SDL_GetControllerMappingFilePath(szControllerMapPath, sizeof(szControllerMapPath))) { + SDL_GameControllerAddMappingsFromFile(szControllerMapPath); + } + /* load in any user supplied config */ SDL_GameControllerLoadHints(); diff --git a/src/joystick/SDL_gamecontrollerdb.h b/src/joystick/SDL_gamecontrollerdb.h index 8caf8477cc..9583c9321e 100644 --- a/src/joystick/SDL_gamecontrollerdb.h +++ b/src/joystick/SDL_gamecontrollerdb.h @@ -191,6 +191,10 @@ static const char *s_ControllerMappings [] = "03000000a30600000cff000010010000,Saitek P2500 Force Rumble Pad,a:b2,b:b3,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,x:b0,y:b1,", "03000000a30600000b04000000010000,Saitek P990 Dual Analog Pad,a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b8,x:b0,y:b3,", "03000000de2800000211000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,", + "05000000de2800000511000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,", + "03000000de2800000112000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,", + "05000000de2800000212000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,", + "03000000de2800004211000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,", "03000000de280000fc11000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", "03000000de280000ff11000001000000,Steam Virtual Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", "xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", @@ -201,13 +205,18 @@ static const char *s_ControllerMappings [] = "03000000830500006020000010010000,iBuffalo SNES Controller,a:b1,b:b0,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b2,", #endif #if defined(__ANDROID__) + "64633436313965656664373634323364,Microsoft X-Box 360 pad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,x:b2,y:b3,", "4e564944494120436f72706f72617469,NVIDIA Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", + "61363931656135336130663561616264,NVIDIA Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", + "37336435666338653565313731303834,NVIDIA Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", + "35643031303033326130316330353564,PS4 Controller,a:b1,b:b17,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b3,leftstick:b4,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b6,righttrigger:+a4,rightx:a2,righty:a5,start:b16,x:b0,y:b2,", + "05000000de2800000511000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,", + "34356136633366613530316338376136,Xbox Wireless Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b3,leftstick:b15,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b16,righttrigger:a5,rightx:a3,righty:a4,x:b17,y:b2,", #endif #if defined(SDL_JOYSTICK_MFI) "4d466947616d65706164010000000000,MFi Extended Gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,", "4d466947616d65706164020000000000,MFi Gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,rightshoulder:b5,start:b6,x:b2,y:b3,", - "03000000de2800000211000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,", - "03000000de280000fc11000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", + "05000000de2800000511000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,", #endif #if defined(SDL_JOYSTICK_EMSCRIPTEN) "emscripten,Standard Gamepad,a:b0,b:b1,back:b8,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,guide:b16,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,", diff --git a/src/joystick/android/SDL_sysjoystick.c b/src/joystick/android/SDL_sysjoystick.c index 59adb85bd2..05f1bcde1d 100644 --- a/src/joystick/android/SDL_sysjoystick.c +++ b/src/joystick/android/SDL_sysjoystick.c @@ -35,6 +35,7 @@ #include "SDL_sysjoystick_c.h" #include "../SDL_joystick_c.h" #include "../../core/android/SDL_android.h" +#include "../steam/SDL_steamcontroller.h" #include "android/keycodes.h" @@ -216,7 +217,7 @@ Android_OnJoy(int device_id, int axis, float value) /* Android gives joy info normalized as [-1.0, 1.0] or [0.0, 1.0] */ SDL_joylist_item *item = JoystickByDeviceId(device_id); if (item && item->joystick) { - SDL_PrivateJoystickAxis(item->joystick, axis, (Sint16) (32767.*value) ); + SDL_PrivateJoystickAxis(item->joystick, axis, (Sint16) (32767.*value)); } return 0; @@ -234,7 +235,7 @@ Android_OnHat(int device_id, int hat_id, int x, int y) if (x >= -1 && x <=1 && y >= -1 && y <= 1) { SDL_joylist_item *item = JoystickByDeviceId(device_id); if (item && item->joystick) { - SDL_PrivateJoystickHat(item->joystick, hat_id, position_map[y+1][x+1] ); + SDL_PrivateJoystickHat(item->joystick, hat_id, position_map[y+1][x+1]); } return 0; } @@ -254,8 +255,8 @@ Android_AddJoystick(int device_id, const char *name, const char *desc, SDL_bool } /* the GUID is just the first 16 chars of the name for now */ - SDL_zero( guid ); - SDL_memcpy( &guid, desc, SDL_min( sizeof(guid), SDL_strlen( desc) ) ); + SDL_zero(guid); + SDL_memcpy(&guid, desc, SDL_min(sizeof(guid), SDL_strlen(desc))); item = (SDL_joylist_item *) SDL_malloc(sizeof (SDL_joylist_item)); if (item == NULL) { @@ -266,7 +267,7 @@ Android_AddJoystick(int device_id, const char *name, const char *desc, SDL_bool item->guid = guid; item->device_id = device_id; item->name = SDL_strdup(name); - if ( item->name == NULL ) { + if (item->name == NULL) { SDL_free(item); return -1; } @@ -349,6 +350,79 @@ Android_RemoveJoystick(int device_id) } +static SDL_bool SteamControllerConnectedCallback(const char *name, SDL_JoystickGUID guid, int *device_instance) +{ + SDL_joylist_item *item; + + item = (SDL_joylist_item *)SDL_calloc(1, sizeof (SDL_joylist_item)); + if (item == NULL) { + return SDL_FALSE; + } + + *device_instance = item->device_instance = instance_counter++; + item->device_id = -1; + item->name = SDL_strdup(name); + item->guid = guid; + SDL_GetSteamControllerInputs(&item->nbuttons, + &item->naxes, + &item->nhats); + item->m_bSteamController = SDL_TRUE; + + if (SDL_joylist_tail == NULL) { + SDL_joylist = SDL_joylist_tail = item; + } else { + SDL_joylist_tail->next = item; + SDL_joylist_tail = item; + } + + /* Need to increment the joystick count before we post the event */ + ++numjoysticks; + + SDL_PrivateJoystickAdded(numjoysticks - 1); + + return SDL_TRUE; +} + +static void SteamControllerDisconnectedCallback(int device_instance) +{ + SDL_joylist_item *item = SDL_joylist; + SDL_joylist_item *prev = NULL; + + while (item != NULL) { + if (item->device_instance == device_instance) { + break; + } + prev = item; + item = item->next; + } + + if (item == NULL) { + return; + } + + if (item->joystick) { + item->joystick->hwdata = NULL; + } + + if (prev != NULL) { + prev->next = item->next; + } else { + SDL_assert(SDL_joylist == item); + SDL_joylist = item->next; + } + if (item == SDL_joylist_tail) { + SDL_joylist_tail = prev; + } + + /* Need to decrement the joystick count before we post the event */ + --numjoysticks; + + SDL_PrivateJoystickRemoved(item->device_instance); + + SDL_free(item->name); + SDL_free(item); +} + int SDL_SYS_JoystickInit(void) { @@ -359,6 +433,9 @@ SDL_SYS_JoystickInit(void) Android_AddJoystick(ANDROID_ACCELEROMETER_DEVICE_ID, ANDROID_ACCELEROMETER_NAME, ANDROID_ACCELEROMETER_NAME, SDL_TRUE, 0, 3, 0, 0); } + SDL_InitSteamControllers(SteamControllerConnectedCallback, + SteamControllerDisconnectedCallback); + return (numjoysticks); } @@ -381,6 +458,8 @@ SDL_SYS_JoystickDetect(void) timeout = SDL_GetTicks() + 3000; Android_JNI_PollInputDevices(); } + + SDL_UpdateSteamControllers(); } static SDL_joylist_item * @@ -449,7 +528,7 @@ SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index) { SDL_joylist_item *item = JoystickByDevIndex(device_index); - if (item == NULL ) { + if (item == NULL) { return SDL_SetError("No such device"); } @@ -477,30 +556,34 @@ SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick) void SDL_SYS_JoystickUpdate(SDL_Joystick * joystick) { - int i; - Sint16 value; - float values[3]; - SDL_joylist_item *item = SDL_joylist; + SDL_joylist_item *item = (SDL_joylist_item *) joystick->hwdata; - while (item) { - if (item->is_accelerometer) { - if (item->joystick) { - if (Android_JNI_GetAccelerometerValues(values)) { - for ( i = 0; i < 3; i++ ) { - if (values[i] > 1.0f) { - values[i] = 1.0f; - } else if (values[i] < -1.0f) { - values[i] = -1.0f; - } - - value = (Sint16)(values[i] * 32767.0f); - SDL_PrivateJoystickAxis(item->joystick, i, value); - } + if (item == NULL) { + return; + } + + if (item->m_bSteamController) { + SDL_UpdateSteamController(joystick); + return; + } + + if (item->is_accelerometer) { + int i; + Sint16 value; + float values[3]; + + if (Android_JNI_GetAccelerometerValues(values)) { + for (i = 0; i < 3; i++) { + if (values[i] > 1.0f) { + values[i] = 1.0f; + } else if (values[i] < -1.0f) { + values[i] = -1.0f; } + + value = (Sint16)(values[i] * 32767.0f); + SDL_PrivateJoystickAxis(item->joystick, i, value); } - break; } - item = item->next; } } @@ -518,6 +601,10 @@ SDL_SYS_JoystickClose(SDL_Joystick * joystick) void SDL_SYS_JoystickQuit(void) { +/* We don't have any way to scan for joysticks at init, so don't wipe the list + * of joysticks here in case this is a reinit. + */ +#if 0 SDL_joylist_item *item = NULL; SDL_joylist_item *next = NULL; @@ -531,9 +618,12 @@ SDL_SYS_JoystickQuit(void) numjoysticks = 0; instance_counter = 0; +#endif /* 0 */ + + SDL_QuitSteamControllers(); } -SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID( int device_index ) +SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID(int device_index) { return JoystickByDevIndex(device_index)->guid; } diff --git a/src/joystick/android/SDL_sysjoystick_c.h b/src/joystick/android/SDL_sysjoystick_c.h index cae7aff168..5002222e3d 100644 --- a/src/joystick/android/SDL_sysjoystick_c.h +++ b/src/joystick/android/SDL_sysjoystick_c.h @@ -46,6 +46,9 @@ typedef struct SDL_joylist_item SDL_Joystick *joystick; int nbuttons, naxes, nhats, nballs; + /* Steam Controller support */ + SDL_bool m_bSteamController; + struct SDL_joylist_item *next; } SDL_joylist_item; diff --git a/src/joystick/iphoneos/SDL_sysjoystick.m b/src/joystick/iphoneos/SDL_sysjoystick.m index 3af5350be1..ec0b2e1e0a 100644 --- a/src/joystick/iphoneos/SDL_sysjoystick.m +++ b/src/joystick/iphoneos/SDL_sysjoystick.m @@ -26,12 +26,15 @@ /* needed for SDL_IPHONE_MAX_GFORCE macro */ #include "SDL_config_iphoneos.h" +#include "SDL_assert.h" #include "SDL_events.h" #include "SDL_joystick.h" #include "SDL_hints.h" #include "SDL_stdinc.h" #include "../SDL_sysjoystick.h" #include "../SDL_joystick_c.h" +#include "../steam/SDL_steamcontroller.h" + #if !SDL_EVENTS_DISABLED #include "../../events/SDL_events_c.h" @@ -242,7 +245,7 @@ --numjoysticks; - SDL_PrivateJoystickRemoved(device->instance_id); + SDL_PrivateJoystickRemoved(device->instance_id); SDL_free(device->name); SDL_free(device); @@ -266,6 +269,50 @@ } #endif /* TARGET_OS_TV */ +static SDL_bool SteamControllerConnectedCallback(const char *name, SDL_JoystickGUID guid, int *device_instance) +{ + SDL_JoystickDeviceItem *device = (SDL_JoystickDeviceItem *)SDL_calloc(1, sizeof(SDL_JoystickDeviceItem)); + if (device == NULL) { + return SDL_FALSE; + } + + *device_instance = device->instance_id = instancecounter++; + device->name = SDL_strdup(name); + device->guid = guid; + SDL_GetSteamControllerInputs(&device->nbuttons, + &device->naxes, + &device->nhats); + device->m_bSteamController = SDL_TRUE; + + if (deviceList == NULL) { + deviceList = device; + } else { + SDL_JoystickDeviceItem *lastdevice = deviceList; + while (lastdevice->next != NULL) { + lastdevice = lastdevice->next; + } + lastdevice->next = device; + } + + ++numjoysticks; + + SDL_PrivateJoystickAdded(numjoysticks - 1); + + return SDL_TRUE; +} + +static void SteamControllerDisconnectedCallback(int device_instance) +{ + SDL_JoystickDeviceItem *item; + + for (item = deviceList; item; item = item->next) { + if (item->instance_id == device_instance) { + SDL_SYS_RemoveJoystickDevice(item); + break; + } + } +} + /* Function to scan the system for joysticks. * Joystick 0 should be the system default joystick. * It should return 0, or -1 on an unrecoverable fatal error. @@ -276,6 +323,9 @@ @autoreleasepool { NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; + SDL_InitSteamControllers(SteamControllerConnectedCallback, + SteamControllerDisconnectedCallback); + #if !TARGET_OS_TV if (SDL_GetHintBoolean(SDL_HINT_ACCELEROMETER_AS_JOYSTICK, SDL_TRUE)) { /* Default behavior, accelerometer as joystick */ @@ -335,6 +385,7 @@ void SDL_SYS_JoystickDetect(void) { + SDL_UpdateSteamControllers(); } /* Function to get the device-dependent name of a joystick */ @@ -628,6 +679,11 @@ SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index) if (device == NULL) { return; } + + if (device->m_bSteamController) { + SDL_UpdateSteamController(joystick); + return; + } if (device->accelerometer) { SDL_SYS_AccelerometerUpdate(joystick); @@ -696,6 +752,8 @@ SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index) #endif /* !TARGET_OS_TV */ } + SDL_QuitSteamControllers(); + numjoysticks = 0; } diff --git a/src/joystick/iphoneos/SDL_sysjoystick_c.h b/src/joystick/iphoneos/SDL_sysjoystick_c.h index dc0e7beeb5..30edb999ec 100644 --- a/src/joystick/iphoneos/SDL_sysjoystick_c.h +++ b/src/joystick/iphoneos/SDL_sysjoystick_c.h @@ -44,6 +44,9 @@ typedef struct joystick_hwdata int nbuttons; int nhats; + /* Steam Controller support */ + SDL_bool m_bSteamController; + struct joystick_hwdata *next; } joystick_hwdata; diff --git a/src/joystick/linux/SDL_sysjoystick.c b/src/joystick/linux/SDL_sysjoystick.c index 1f19d1d392..84d99a2c2b 100644 --- a/src/joystick/linux/SDL_sysjoystick.c +++ b/src/joystick/linux/SDL_sysjoystick.c @@ -38,8 +38,10 @@ #include "SDL_assert.h" #include "SDL_joystick.h" #include "SDL_endian.h" +#include "../../events/SDL_events_c.h" #include "../SDL_sysjoystick.h" #include "../SDL_joystick_c.h" +#include "../steam/SDL_steamcontroller.h" #include "SDL_sysjoystick_c.h" /* This isn't defined in older Linux kernel headers */ @@ -66,6 +68,9 @@ typedef struct SDL_joylist_item dev_t devnum; struct joystick_hwdata *hwdata; struct SDL_joylist_item *next; + + /* Steam Controller support */ + SDL_bool m_bSteamController; } SDL_joylist_item; static SDL_joylist_item *SDL_joylist = NULL; @@ -73,6 +78,7 @@ static SDL_joylist_item *SDL_joylist_tail = NULL; static int numjoysticks = 0; static int instance_counter = 0; + #define test_bit(nr, addr) \ (((1UL << ((nr) % (sizeof(long) * 8))) & ((addr)[(nr) / (sizeof(long) * 8)])) != 0) #define NBITS(x) ((((x)-1)/(sizeof(long) * 8))+1) @@ -428,6 +434,77 @@ JoystickInitWithUdev(void) } #endif +static SDL_bool SteamControllerConnectedCallback(const char *name, SDL_JoystickGUID guid, int *device_instance) +{ + SDL_joylist_item *item; + + item = (SDL_joylist_item *) SDL_calloc(1, sizeof (SDL_joylist_item)); + if (item == NULL) { + return SDL_FALSE; + } + + item->path = SDL_strdup(""); + item->name = SDL_strdup(name); + item->guid = guid; + item->m_bSteamController = SDL_TRUE; + + if ((item->path == NULL) || (item->name == NULL)) { + SDL_free(item->path); + SDL_free(item->name); + SDL_free(item); + return SDL_FALSE; + } + + *device_instance = item->device_instance = instance_counter++; + if (SDL_joylist_tail == NULL) { + SDL_joylist = SDL_joylist_tail = item; + } else { + SDL_joylist_tail->next = item; + SDL_joylist_tail = item; + } + + /* Need to increment the joystick count before we post the event */ + ++numjoysticks; + + SDL_PrivateJoystickAdded(numjoysticks - 1); + + return SDL_TRUE; +} + +static void SteamControllerDisconnectedCallback(int device_instance) +{ + SDL_joylist_item *item; + SDL_joylist_item *prev = NULL; + + for (item = SDL_joylist; item != NULL; item = item->next) { + /* found it, remove it. */ + if (item->device_instance == device_instance) { + if (item->hwdata) { + item->hwdata->item = NULL; + } + if (prev != NULL) { + prev->next = item->next; + } else { + SDL_assert(SDL_joylist == item); + SDL_joylist = item->next; + } + if (item == SDL_joylist_tail) { + SDL_joylist_tail = prev; + } + + /* Need to decrement the joystick count before we post the event */ + --numjoysticks; + + SDL_PrivateJoystickRemoved(item->device_instance); + + SDL_free(item->name); + SDL_free(item); + return; + } + prev = item; + } +} + int SDL_SYS_JoystickInit(void) { @@ -447,6 +524,9 @@ SDL_SYS_JoystickInit(void) SDL_free(envcopy); } + SDL_InitSteamControllers(SteamControllerConnectedCallback, + SteamControllerDisconnectedCallback); + #if SDL_USE_LIBUDEV return JoystickInitWithUdev(); #else @@ -466,7 +546,8 @@ SDL_SYS_JoystickDetect(void) #if SDL_USE_LIBUDEV SDL_UDEV_Poll(); #endif - + + SDL_UpdateSteamControllers(); } static SDL_joylist_item * @@ -650,47 +731,53 @@ int SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index) { SDL_joylist_item *item = JoystickByDevIndex(device_index); - char *fname = NULL; - int fd = -1; if (item == NULL) { return SDL_SetError("No such device"); } - fname = item->path; - fd = open(fname, O_RDONLY, 0); - if (fd < 0) { - return SDL_SetError("Unable to open %s", fname); - } - joystick->instance_id = item->device_instance; joystick->hwdata = (struct joystick_hwdata *) - SDL_malloc(sizeof(*joystick->hwdata)); + SDL_calloc(1, sizeof(*joystick->hwdata)); if (joystick->hwdata == NULL) { - close(fd); return SDL_OutOfMemory(); } - SDL_memset(joystick->hwdata, 0, sizeof(*joystick->hwdata)); joystick->hwdata->item = item; joystick->hwdata->guid = item->guid; - joystick->hwdata->fd = fd; - joystick->hwdata->fname = SDL_strdup(item->path); - if (joystick->hwdata->fname == NULL) { - SDL_free(joystick->hwdata); - joystick->hwdata = NULL; - close(fd); - return SDL_OutOfMemory(); + joystick->hwdata->m_bSteamController = item->m_bSteamController; + + if (item->m_bSteamController) { + joystick->hwdata->fd = -1; + SDL_GetSteamControllerInputs(&joystick->nbuttons, + &joystick->naxes, + &joystick->nhats); + } else { + int fd = open(item->path, O_RDONLY, 0); + if (fd < 0) { + SDL_free(joystick->hwdata); + joystick->hwdata = NULL; + return SDL_SetError("Unable to open %s", item->path); + } + + joystick->hwdata->fd = fd; + joystick->hwdata->fname = SDL_strdup(item->path); + if (joystick->hwdata->fname == NULL) { + SDL_free(joystick->hwdata); + joystick->hwdata = NULL; + close(fd); + return SDL_OutOfMemory(); + } + + /* Set the joystick to non-blocking read mode */ + fcntl(fd, F_SETFL, O_NONBLOCK); + + /* Get the number of buttons and axes on the joystick */ + ConfigJoystick(joystick, fd); } SDL_assert(item->hwdata == NULL); item->hwdata = joystick->hwdata; - /* Set the joystick to non-blocking read mode */ - fcntl(fd, F_SETFL, O_NONBLOCK); - - /* Get the number of buttons and axes on the joystick */ - ConfigJoystick(joystick, fd); - /* mark joystick as fresh and ready */ joystick->hwdata->fresh = 1; @@ -881,6 +968,11 @@ SDL_SYS_JoystickUpdate(SDL_Joystick * joystick) { int i; + if (joystick->hwdata->m_bSteamController) { + SDL_UpdateSteamController(joystick); + return; + } + HandleInputEvents(joystick); /* Deliver ball motion updates */ @@ -902,7 +994,9 @@ void SDL_SYS_JoystickClose(SDL_Joystick * joystick) { if (joystick->hwdata) { - close(joystick->hwdata->fd); + if (joystick->hwdata->fd >= 0) { + close(joystick->hwdata->fd); + } if (joystick->hwdata->item) { joystick->hwdata->item->hwdata = NULL; } @@ -936,6 +1030,8 @@ SDL_SYS_JoystickQuit(void) SDL_UDEV_DelCallback(joystick_udev_callback); SDL_UDEV_Quit(); #endif + + SDL_QuitSteamControllers(); } SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID( int device_index ) diff --git a/src/joystick/linux/SDL_sysjoystick_c.h b/src/joystick/linux/SDL_sysjoystick_c.h index 5c2ed5bec6..0743c6e588 100644 --- a/src/joystick/linux/SDL_sysjoystick_c.h +++ b/src/joystick/linux/SDL_sysjoystick_c.h @@ -52,6 +52,9 @@ struct joystick_hwdata } abs_correct[ABS_MAX]; int fresh; + + /* Steam Controller support */ + SDL_bool m_bSteamController; }; /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/joystick/steam/SDL_steamcontroller.c b/src/joystick/steam/SDL_steamcontroller.c new file mode 100644 index 0000000000..e91830a49e --- /dev/null +++ b/src/joystick/steam/SDL_steamcontroller.c @@ -0,0 +1,52 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2017 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. +*/ +#include "../../SDL_internal.h" + +#include "../SDL_sysjoystick.h" +#include "../SDL_joystick_c.h" +#include "SDL_steamcontroller.h" + + +void SDL_InitSteamControllers(SteamControllerConnectedCallback_t connectedCallback, + SteamControllerDisconnectedCallback_t disconnectedCallback) +{ +} + +void SDL_GetSteamControllerInputs(int *nbuttons, int *naxes, int *nhats) +{ + *nbuttons = 0; + *naxes = 0; + *nhats = 0; +} + +void SDL_UpdateSteamControllers() +{ +} + +void SDL_UpdateSteamController(SDL_Joystick *joystick) +{ +} + +void SDL_QuitSteamControllers() +{ +} + +/* vi: set ts=4 sw=4 expandtab: */ From ba65dd44a30d9cde59c7ede78bc5d6ba55444183 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 22 Sep 2017 08:30:58 -0700 Subject: [PATCH 08/95] Removed non-existent files --- configure | 1 - configure.in | 1 - 2 files changed, 2 deletions(-) diff --git a/configure b/configure index 53a5af427f..b3cf33a340 100755 --- a/configure +++ b/configure @@ -16846,7 +16846,6 @@ fi SOURCES="$SOURCES $srcdir/src/*.c" SOURCES="$SOURCES $srcdir/src/atomic/*.c" SOURCES="$SOURCES $srcdir/src/audio/*.c" -SOURCES="$SOURCES $srcdir/src/audio/marvell/*.c" SOURCES="$SOURCES $srcdir/src/cpuinfo/*.c" SOURCES="$SOURCES $srcdir/src/dynapi/*.c" SOURCES="$SOURCES $srcdir/src/events/*.c" diff --git a/configure.in b/configure.in index 759ba363e3..0feb0ebe07 100644 --- a/configure.in +++ b/configure.in @@ -325,7 +325,6 @@ fi SOURCES="$SOURCES $srcdir/src/*.c" SOURCES="$SOURCES $srcdir/src/atomic/*.c" SOURCES="$SOURCES $srcdir/src/audio/*.c" -SOURCES="$SOURCES $srcdir/src/audio/marvell/*.c" SOURCES="$SOURCES $srcdir/src/cpuinfo/*.c" SOURCES="$SOURCES $srcdir/src/dynapi/*.c" SOURCES="$SOURCES $srcdir/src/events/*.c" From 3eaf12c09089091e1093c9e7fef6d6b544af0d45 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 22 Sep 2017 08:31:02 -0700 Subject: [PATCH 09/95] Removed non-existent files --- Android.mk | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Android.mk b/Android.mk index ac770d9036..d593d68d28 100755 --- a/Android.mk +++ b/Android.mk @@ -32,7 +32,6 @@ LOCAL_SRC_FILES := \ $(wildcard $(LOCAL_PATH)/src/joystick/*.c) \ $(wildcard $(LOCAL_PATH)/src/joystick/android/*.c) \ $(LOCAL_PATH)/src/joystick/steam/SDL_steamcontroller.c \ - $(LOCAL_PATH)/src/joystick/steam/steamcontroller_hidapi.c \ $(wildcard $(LOCAL_PATH)/src/loadso/dlopen/*.c) \ $(wildcard $(LOCAL_PATH)/src/power/*.c) \ $(wildcard $(LOCAL_PATH)/src/power/android/*.c) \ @@ -46,9 +45,7 @@ LOCAL_SRC_FILES := \ $(wildcard $(LOCAL_PATH)/src/timer/unix/*.c) \ $(wildcard $(LOCAL_PATH)/src/video/*.c) \ $(wildcard $(LOCAL_PATH)/src/video/android/*.c) \ - $(wildcard $(LOCAL_PATH)/src/test/*.c)) \ - -LOCAL_SHARED_LIBRARIES := hidapi + $(wildcard $(LOCAL_PATH)/src/test/*.c)) LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES LOCAL_LDLIBS := -ldl -lGLESv1_CM -lGLESv2 -llog -landroid From dffba9fa0be2a2bac1862d2e125d645e923ecd12 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 22 Sep 2017 08:31:56 -0700 Subject: [PATCH 10/95] Separated out SDL Android java code so audio, controller, and filesystem APIs can be used independently of the SDL activity, in Qt apps for example. --- android-project/src/org/libsdl/app/SDL.java | 37 ++ .../src/org/libsdl/app/SDLAudioManager.java | 179 ++++++++ .../org/libsdl/app/SDLControllerManager.java | 427 ++++++++++++++++++ 3 files changed, 643 insertions(+) create mode 100644 android-project/src/org/libsdl/app/SDL.java create mode 100644 android-project/src/org/libsdl/app/SDLAudioManager.java create mode 100644 android-project/src/org/libsdl/app/SDLControllerManager.java diff --git a/android-project/src/org/libsdl/app/SDL.java b/android-project/src/org/libsdl/app/SDL.java new file mode 100644 index 0000000000..cfe4830945 --- /dev/null +++ b/android-project/src/org/libsdl/app/SDL.java @@ -0,0 +1,37 @@ +package org.libsdl.app; + +import android.content.Context; + +/** + SDL library initialization +*/ +public class SDL { + + // This function should be called first and sets up the native code + // so it can call into the Java classes + public static void setupJNI() { + SDLActivity.nativeSetupJNI(); + SDLAudioManager.nativeSetupJNI(); + SDLControllerManager.nativeSetupJNI(); + } + + // This function should be called each time the activity is started + public static void initialize() { + setContext(null); + + SDLActivity.initialize(); + SDLAudioManager.initialize(); + SDLControllerManager.initialize(); + } + + // This function stores the current activity (SDL or not) + public static void setContext(Context context) { + mContext = context; + } + + public static Context getContext() { + return mContext; + } + + protected static Context mContext; +} diff --git a/android-project/src/org/libsdl/app/SDLAudioManager.java b/android-project/src/org/libsdl/app/SDLAudioManager.java new file mode 100644 index 0000000000..66c3fea422 --- /dev/null +++ b/android-project/src/org/libsdl/app/SDLAudioManager.java @@ -0,0 +1,179 @@ +package org.libsdl.app; + +import android.media.*; +import android.hardware.*; +import android.util.Log; + +public class SDLAudioManager +{ + protected static final String TAG = "SDLAudio"; + + protected static AudioTrack mAudioTrack; + protected static AudioRecord mAudioRecord; + + public static void initialize() { + mAudioTrack = null; + mAudioRecord = null; + } + + // Audio + + /** + * This method is called by SDL using JNI. + */ + public static int audioOpen(int sampleRate, boolean is16Bit, boolean isStereo, int desiredFrames) { + int channelConfig = isStereo ? AudioFormat.CHANNEL_CONFIGURATION_STEREO : AudioFormat.CHANNEL_CONFIGURATION_MONO; + int audioFormat = is16Bit ? AudioFormat.ENCODING_PCM_16BIT : AudioFormat.ENCODING_PCM_8BIT; + int frameSize = (isStereo ? 2 : 1) * (is16Bit ? 2 : 1); + + Log.v(TAG, "SDL audio: wanted " + (isStereo ? "stereo" : "mono") + " " + (is16Bit ? "16-bit" : "8-bit") + " " + (sampleRate / 1000f) + "kHz, " + desiredFrames + " frames buffer"); + + // Let the user pick a larger buffer if they really want -- but ye + // gods they probably shouldn't, the minimums are horrifyingly high + // latency already + desiredFrames = Math.max(desiredFrames, (AudioTrack.getMinBufferSize(sampleRate, channelConfig, audioFormat) + frameSize - 1) / frameSize); + + if (mAudioTrack == null) { + mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate, + channelConfig, audioFormat, desiredFrames * frameSize, AudioTrack.MODE_STREAM); + + // Instantiating AudioTrack can "succeed" without an exception and the track may still be invalid + // Ref: https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/media/java/android/media/AudioTrack.java + // Ref: http://developer.android.com/reference/android/media/AudioTrack.html#getState() + + if (mAudioTrack.getState() != AudioTrack.STATE_INITIALIZED) { + Log.e(TAG, "Failed during initialization of Audio Track"); + mAudioTrack = null; + return -1; + } + + mAudioTrack.play(); + } + + Log.v(TAG, "SDL audio: got " + ((mAudioTrack.getChannelCount() >= 2) ? "stereo" : "mono") + " " + ((mAudioTrack.getAudioFormat() == AudioFormat.ENCODING_PCM_16BIT) ? "16-bit" : "8-bit") + " " + (mAudioTrack.getSampleRate() / 1000f) + "kHz, " + desiredFrames + " frames buffer"); + + return 0; + } + + /** + * This method is called by SDL using JNI. + */ + public static void audioWriteShortBuffer(short[] buffer) { + if (mAudioTrack == null) { + Log.e(TAG, "Attempted to make audio call with uninitialized audio!"); + return; + } + + for (int i = 0; i < buffer.length; ) { + int result = mAudioTrack.write(buffer, i, buffer.length - i); + if (result > 0) { + i += result; + } else if (result == 0) { + try { + Thread.sleep(1); + } catch(InterruptedException e) { + // Nom nom + } + } else { + Log.w(TAG, "SDL audio: error return from write(short)"); + return; + } + } + } + + /** + * This method is called by SDL using JNI. + */ + public static void audioWriteByteBuffer(byte[] buffer) { + if (mAudioTrack == null) { + Log.e(TAG, "Attempted to make audio call with uninitialized audio!"); + return; + } + + for (int i = 0; i < buffer.length; ) { + int result = mAudioTrack.write(buffer, i, buffer.length - i); + if (result > 0) { + i += result; + } else if (result == 0) { + try { + Thread.sleep(1); + } catch(InterruptedException e) { + // Nom nom + } + } else { + Log.w(TAG, "SDL audio: error return from write(byte)"); + return; + } + } + } + + /** + * This method is called by SDL using JNI. + */ + public static int captureOpen(int sampleRate, boolean is16Bit, boolean isStereo, int desiredFrames) { + int channelConfig = isStereo ? AudioFormat.CHANNEL_CONFIGURATION_STEREO : AudioFormat.CHANNEL_CONFIGURATION_MONO; + int audioFormat = is16Bit ? AudioFormat.ENCODING_PCM_16BIT : AudioFormat.ENCODING_PCM_8BIT; + int frameSize = (isStereo ? 2 : 1) * (is16Bit ? 2 : 1); + + Log.v(TAG, "SDL capture: wanted " + (isStereo ? "stereo" : "mono") + " " + (is16Bit ? "16-bit" : "8-bit") + " " + (sampleRate / 1000f) + "kHz, " + desiredFrames + " frames buffer"); + + // Let the user pick a larger buffer if they really want -- but ye + // gods they probably shouldn't, the minimums are horrifyingly high + // latency already + desiredFrames = Math.max(desiredFrames, (AudioRecord.getMinBufferSize(sampleRate, channelConfig, audioFormat) + frameSize - 1) / frameSize); + + if (mAudioRecord == null) { + mAudioRecord = new AudioRecord(MediaRecorder.AudioSource.DEFAULT, sampleRate, + channelConfig, audioFormat, desiredFrames * frameSize); + + // see notes about AudioTrack state in audioOpen(), above. Probably also applies here. + if (mAudioRecord.getState() != AudioRecord.STATE_INITIALIZED) { + Log.e(TAG, "Failed during initialization of AudioRecord"); + mAudioRecord.release(); + mAudioRecord = null; + return -1; + } + + mAudioRecord.startRecording(); + } + + Log.v(TAG, "SDL capture: got " + ((mAudioRecord.getChannelCount() >= 2) ? "stereo" : "mono") + " " + ((mAudioRecord.getAudioFormat() == AudioFormat.ENCODING_PCM_16BIT) ? "16-bit" : "8-bit") + " " + (mAudioRecord.getSampleRate() / 1000f) + "kHz, " + desiredFrames + " frames buffer"); + + return 0; + } + + /** This method is called by SDL using JNI. */ + public static int captureReadShortBuffer(short[] buffer, boolean blocking) { + // !!! FIXME: this is available in API Level 23. Until then, we always block. :( + //return mAudioRecord.read(buffer, 0, buffer.length, blocking ? AudioRecord.READ_BLOCKING : AudioRecord.READ_NON_BLOCKING); + return mAudioRecord.read(buffer, 0, buffer.length); + } + + /** This method is called by SDL using JNI. */ + public static int captureReadByteBuffer(byte[] buffer, boolean blocking) { + // !!! FIXME: this is available in API Level 23. Until then, we always block. :( + //return mAudioRecord.read(buffer, 0, buffer.length, blocking ? AudioRecord.READ_BLOCKING : AudioRecord.READ_NON_BLOCKING); + return mAudioRecord.read(buffer, 0, buffer.length); + } + + + /** This method is called by SDL using JNI. */ + public static void audioClose() { + if (mAudioTrack != null) { + mAudioTrack.stop(); + mAudioTrack.release(); + mAudioTrack = null; + } + } + + /** This method is called by SDL using JNI. */ + public static void captureClose() { + if (mAudioRecord != null) { + mAudioRecord.stop(); + mAudioRecord.release(); + mAudioRecord = null; + } + } + + public static native int nativeSetupJNI(); +} diff --git a/android-project/src/org/libsdl/app/SDLControllerManager.java b/android-project/src/org/libsdl/app/SDLControllerManager.java new file mode 100644 index 0000000000..c050764dab --- /dev/null +++ b/android-project/src/org/libsdl/app/SDLControllerManager.java @@ -0,0 +1,427 @@ +package org.libsdl.app; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +import android.app.*; +import android.content.Context; +import android.hardware.*; +import android.os.*; +import android.view.*; +import android.util.Log; + + +public class SDLControllerManager +{ + + public static native int nativeSetupJNI(); + + public static native int nativeAddJoystick(int device_id, String name, String desc, + int is_accelerometer, int nbuttons, + int naxes, int nhats, int nballs); + public static native int nativeRemoveJoystick(int device_id); + public static native int nativeAddHaptic(int device_id, String name); + public static native int nativeRemoveHaptic(int device_id); + public static native int onNativePadDown(int device_id, int keycode); + public static native int onNativePadUp(int device_id, int keycode); + public static native void onNativeJoy(int device_id, int axis, + float value); + public static native void onNativeHat(int device_id, int hat_id, + int x, int y); + + protected static SDLJoystickHandler mJoystickHandler; + protected static SDLHapticHandler mHapticHandler; + + private static final String TAG = "SDLControllerManager"; + + public static void initialize() { + mJoystickHandler = null; + mHapticHandler = null; + + SDLControllerManager.setup(); + } + + public static void setup() { + if (Build.VERSION.SDK_INT >= 16) { + mJoystickHandler = new SDLJoystickHandler_API16(); + } else if (Build.VERSION.SDK_INT >= 12) { + mJoystickHandler = new SDLJoystickHandler_API12(); + } else { + mJoystickHandler = new SDLJoystickHandler(); + } + mHapticHandler = new SDLHapticHandler(); + } + + // Joystick glue code, just a series of stubs that redirect to the SDLJoystickHandler instance + public static boolean handleJoystickMotionEvent(MotionEvent event) { + return mJoystickHandler.handleMotionEvent(event); + } + + /** + * This method is called by SDL using JNI. + */ + public static void pollInputDevices() { + mJoystickHandler.pollInputDevices(); + } + + /** + * This method is called by SDL using JNI. + */ + public static void pollHapticDevices() { + mHapticHandler.pollHapticDevices(); + } + + /** + * This method is called by SDL using JNI. + */ + public static void hapticRun(int device_id, int length) { + mHapticHandler.run(device_id, length); + } + + // Check if a given device is considered a possible SDL joystick + public static boolean isDeviceSDLJoystick(int deviceId) { + InputDevice device = InputDevice.getDevice(deviceId); + // We cannot use InputDevice.isVirtual before API 16, so let's accept + // only nonnegative device ids (VIRTUAL_KEYBOARD equals -1) + if ((device == null) || (deviceId < 0)) { + return false; + } + int sources = device.getSources(); + + if ((sources & InputDevice.SOURCE_CLASS_JOYSTICK) == InputDevice.SOURCE_CLASS_JOYSTICK) { + Log.v(TAG, "Input device " + device.getName() + " is a joystick."); + } + if ((sources & InputDevice.SOURCE_DPAD) == InputDevice.SOURCE_DPAD) { + Log.v(TAG, "Input device " + device.getName() + " is a dpad."); + } + if ((sources & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD) { + Log.v(TAG, "Input device " + device.getName() + " is a gamepad."); + } + + return (((sources & InputDevice.SOURCE_CLASS_JOYSTICK) == InputDevice.SOURCE_CLASS_JOYSTICK) || + ((sources & InputDevice.SOURCE_DPAD) == InputDevice.SOURCE_DPAD) || + ((sources & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD) + ); + } + +} + +/* A null joystick handler for API level < 12 devices (the accelerometer is handled separately) */ +class SDLJoystickHandler { + + /** + * Handles given MotionEvent. + * @param event the event to be handled. + * @return if given event was processed. + */ + public boolean handleMotionEvent(MotionEvent event) { + return false; + } + + /** + * Handles adding and removing of input devices. + */ + public void pollInputDevices() { + } +} + +/* Actual joystick functionality available for API >= 12 devices */ +class SDLJoystickHandler_API12 extends SDLJoystickHandler { + + static class SDLJoystick { + public int device_id; + public String name; + public String desc; + public ArrayList axes; + public ArrayList hats; + } + static class RangeComparator implements Comparator { + @Override + public int compare(InputDevice.MotionRange arg0, InputDevice.MotionRange arg1) { + return arg0.getAxis() - arg1.getAxis(); + } + } + + private ArrayList mJoysticks; + + public SDLJoystickHandler_API12() { + + mJoysticks = new ArrayList(); + } + + @Override + public void pollInputDevices() { + int[] deviceIds = InputDevice.getDeviceIds(); + // It helps processing the device ids in reverse order + // For example, in the case of the XBox 360 wireless dongle, + // so the first controller seen by SDL matches what the receiver + // considers to be the first controller + + for(int i=deviceIds.length-1; i>-1; i--) { + SDLJoystick joystick = getJoystick(deviceIds[i]); + if (joystick == null) { + joystick = new SDLJoystick(); + InputDevice joystickDevice = InputDevice.getDevice(deviceIds[i]); + if (SDLControllerManager.isDeviceSDLJoystick(deviceIds[i])) { + joystick.device_id = deviceIds[i]; + joystick.name = joystickDevice.getName(); + joystick.desc = getJoystickDescriptor(joystickDevice); + joystick.axes = new ArrayList(); + joystick.hats = new ArrayList(); + + List ranges = joystickDevice.getMotionRanges(); + Collections.sort(ranges, new RangeComparator()); + for (InputDevice.MotionRange range : ranges ) { + if ((range.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) { + if (range.getAxis() == MotionEvent.AXIS_HAT_X || + range.getAxis() == MotionEvent.AXIS_HAT_Y) { + joystick.hats.add(range); + } + else { + joystick.axes.add(range); + } + } + } + + mJoysticks.add(joystick); + SDLControllerManager.nativeAddJoystick(joystick.device_id, joystick.name, joystick.desc, 0, -1, + joystick.axes.size(), joystick.hats.size()/2, 0); + } + } + } + + /* Check removed devices */ + ArrayList removedDevices = new ArrayList(); + for(int i=0; i < mJoysticks.size(); i++) { + int device_id = mJoysticks.get(i).device_id; + int j; + for (j=0; j < deviceIds.length; j++) { + if (device_id == deviceIds[j]) break; + } + if (j == deviceIds.length) { + removedDevices.add(Integer.valueOf(device_id)); + } + } + + for(int i=0; i < removedDevices.size(); i++) { + int device_id = removedDevices.get(i).intValue(); + SDLControllerManager.nativeRemoveJoystick(device_id); + for (int j=0; j < mJoysticks.size(); j++) { + if (mJoysticks.get(j).device_id == device_id) { + mJoysticks.remove(j); + break; + } + } + } + } + + protected SDLJoystick getJoystick(int device_id) { + for(int i=0; i < mJoysticks.size(); i++) { + if (mJoysticks.get(i).device_id == device_id) { + return mJoysticks.get(i); + } + } + return null; + } + + @Override + public boolean handleMotionEvent(MotionEvent event) { + if ((event.getSource() & InputDevice.SOURCE_JOYSTICK) != 0) { + int actionPointerIndex = event.getActionIndex(); + int action = event.getActionMasked(); + switch(action) { + case MotionEvent.ACTION_MOVE: + SDLJoystick joystick = getJoystick(event.getDeviceId()); + if ( joystick != null ) { + for (int i = 0; i < joystick.axes.size(); i++) { + InputDevice.MotionRange range = joystick.axes.get(i); + /* Normalize the value to -1...1 */ + float value = ( event.getAxisValue( range.getAxis(), actionPointerIndex) - range.getMin() ) / range.getRange() * 2.0f - 1.0f; + SDLControllerManager.onNativeJoy(joystick.device_id, i, value ); + } + for (int i = 0; i < joystick.hats.size(); i+=2) { + int hatX = Math.round(event.getAxisValue( joystick.hats.get(i).getAxis(), actionPointerIndex ) ); + int hatY = Math.round(event.getAxisValue( joystick.hats.get(i+1).getAxis(), actionPointerIndex ) ); + SDLControllerManager.onNativeHat(joystick.device_id, i/2, hatX, hatY ); + } + } + break; + default: + break; + } + } + return true; + } + + public String getJoystickDescriptor(InputDevice joystickDevice) { + return joystickDevice.getName(); + } +} + + +class SDLJoystickHandler_API16 extends SDLJoystickHandler_API12 { + + @Override + public String getJoystickDescriptor(InputDevice joystickDevice) { + String desc = joystickDevice.getDescriptor(); + + if (desc != null && desc != "") { + return desc; + } + + return super.getJoystickDescriptor(joystickDevice); + } +} + +class SDLHapticHandler { + + class SDLHaptic { + public int device_id; + public String name; + public Vibrator vib; + } + + private ArrayList mHaptics; + + public SDLHapticHandler() { + mHaptics = new ArrayList(); + } + + public void run(int device_id, int length) { + SDLHaptic haptic = getHaptic(device_id); + if (haptic != null) { + haptic.vib.vibrate (length); + } + } + + public void pollHapticDevices() { + + final int deviceId_VIBRATOR_SERVICE = 999999; + boolean hasVibrator = false; + + int[] deviceIds = InputDevice.getDeviceIds(); + // It helps processing the device ids in reverse order + // For example, in the case of the XBox 360 wireless dongle, + // so the first controller seen by SDL matches what the receiver + // considers to be the first controller + + for(int i=deviceIds.length-1; i>-1; i--) { + SDLHaptic haptic = getHaptic(deviceIds[i]); + if (haptic == null) { + InputDevice device = InputDevice.getDevice(deviceIds[i]); + Vibrator vib = device.getVibrator(); + if (vib.hasVibrator()) { + haptic = new SDLHaptic(); + haptic.device_id = deviceIds[i]; + haptic.name = device.getName(); + haptic.vib = vib; + mHaptics.add(haptic); + SDLControllerManager.nativeAddHaptic(haptic.device_id, haptic.name); + } + } + } + + /* Check VIBRATOR_SERVICE */ + { + Vibrator vib = (Vibrator) SDL.getContext().getSystemService(Context.VIBRATOR_SERVICE); + if (vib != null && vib.hasVibrator()) { + hasVibrator = true; + SDLHaptic haptic = getHaptic(deviceId_VIBRATOR_SERVICE); + if (haptic == null) { + haptic = new SDLHaptic(); + haptic.device_id = deviceId_VIBRATOR_SERVICE; + haptic.name = "VIBRATOR_SERVICE"; + haptic.vib = vib; + mHaptics.add(haptic); + SDLControllerManager.nativeAddHaptic(haptic.device_id, haptic.name); + } + } + } + + /* Check removed devices */ + ArrayList removedDevices = new ArrayList(); + for(int i=0; i < mHaptics.size(); i++) { + int device_id = mHaptics.get(i).device_id; + int j; + for (j=0; j < deviceIds.length; j++) { + if (device_id == deviceIds[j]) break; + } + + if (device_id == deviceId_VIBRATOR_SERVICE && hasVibrator) { + // don't remove the vibrator if it is still present + } else if (j == deviceIds.length) { + removedDevices.add(device_id); + } + } + + for(int i=0; i < removedDevices.size(); i++) { + int device_id = removedDevices.get(i); + SDLControllerManager.nativeRemoveHaptic(device_id); + for (int j=0; j < mHaptics.size(); j++) { + if (mHaptics.get(j).device_id == device_id) { + mHaptics.remove(j); + break; + } + } + } + } + + protected SDLHaptic getHaptic(int device_id) { + for(int i=0; i < mHaptics.size(); i++) { + if (mHaptics.get(i).device_id == device_id) { + return mHaptics.get(i); + } + } + return null; + } +} + +class SDLGenericMotionListener_API12 implements View.OnGenericMotionListener { + // Generic Motion (mouse hover, joystick...) events go here + @Override + public boolean onGenericMotion(View v, MotionEvent event) { + float x, y; + int action; + + switch ( event.getSource() ) { + case InputDevice.SOURCE_JOYSTICK: + case InputDevice.SOURCE_GAMEPAD: + case InputDevice.SOURCE_DPAD: + return SDLControllerManager.handleJoystickMotionEvent(event); + + case InputDevice.SOURCE_MOUSE: + if (!SDLActivity.mSeparateMouseAndTouch) { + break; + } + action = event.getActionMasked(); + switch (action) { + case MotionEvent.ACTION_SCROLL: + x = event.getAxisValue(MotionEvent.AXIS_HSCROLL, 0); + y = event.getAxisValue(MotionEvent.AXIS_VSCROLL, 0); + SDLActivity.onNativeMouse(0, action, x, y); + return true; + + case MotionEvent.ACTION_HOVER_MOVE: + x = event.getX(0); + y = event.getY(0); + + SDLActivity.onNativeMouse(0, action, x, y); + return true; + + default: + break; + } + break; + + default: + break; + } + + // Event was not managed + return false; + } +} + From 60b54148f956d402232fd65aa338bc2383f22177 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 22 Sep 2017 08:32:31 -0700 Subject: [PATCH 11/95] Added stubs for simple Steam Controller support --- src/joystick/steam/SDL_steamcontroller.h | 33 ++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 src/joystick/steam/SDL_steamcontroller.h diff --git a/src/joystick/steam/SDL_steamcontroller.h b/src/joystick/steam/SDL_steamcontroller.h new file mode 100644 index 0000000000..30a43cb19e --- /dev/null +++ b/src/joystick/steam/SDL_steamcontroller.h @@ -0,0 +1,33 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2017 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. +*/ +#include "../../SDL_internal.h" + +typedef SDL_bool (*SteamControllerConnectedCallback_t)(const char *name, SDL_JoystickGUID guid, int *device_instance); +typedef void (*SteamControllerDisconnectedCallback_t)(int device_instance); + +void SDL_InitSteamControllers(SteamControllerConnectedCallback_t connectedCallback, + SteamControllerDisconnectedCallback_t disconnectedCallback); +void SDL_GetSteamControllerInputs(int *nbuttons, int *naxes, int *nhats); +void SDL_UpdateSteamControllers(); +void SDL_UpdateSteamController(SDL_Joystick *joystick); +void SDL_QuitSteamControllers(); + +/* vi: set ts=4 sw=4 expandtab: */ From 1e60f17452e42e2fa3f6d4beb1ea46007d526b7c Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 22 Sep 2017 16:33:34 -0700 Subject: [PATCH 12/95] Added stub Steam Controller sources to Android and iOS command line builds --- CMakeLists.txt | 6 +++--- configure | 2 ++ configure.in | 2 ++ 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8a5e592a49..33a3f6c5ca 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -816,7 +816,7 @@ if(ANDROID) endif() if(SDL_JOYSTICK) set(SDL_JOYSTICK_ANDROID 1) - file(GLOB ANDROID_JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/android/*.c) + file(GLOB ANDROID_JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/android/*.c ${SDL2_SOURCE_DIR}/src/joystick/steam/*.c) set(SOURCE_FILES ${SOURCE_FILES} ${ANDROID_JOYSTICK_SOURCES}) set(HAVE_SDL_JOYSTICK TRUE) endif() @@ -1055,7 +1055,7 @@ elseif(UNIX AND NOT APPLE AND NOT ANDROID) CheckUSBHID() # seems to be BSD specific - limit the test to BSD only? if(LINUX AND NOT ANDROID) set(SDL_JOYSTICK_LINUX 1) - file(GLOB JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/linux/*.c) + file(GLOB JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/linux/*.c ${SDL2_SOURCE_DIR}/src/joystick/steam/*.c) set(SOURCE_FILES ${SOURCE_FILES} ${JOYSTICK_SOURCES}) set(HAVE_SDL_JOYSTICK TRUE) endif() @@ -1382,7 +1382,7 @@ elseif(APPLE) if(SDL_JOYSTICK) set(SDL_JOYSTICK_IOKIT 1) if (IOS) - file(GLOB JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/iphoneos/*.m) + file(GLOB JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/iphoneos/*.m ${SDL2_SOURCE_DIR}/src/joystick/steam/*.c) else() file(GLOB JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/darwin/*.c) endif() diff --git a/configure b/configure index b3cf33a340..1cb707e2b7 100755 --- a/configure +++ b/configure @@ -23847,6 +23847,7 @@ $as_echo "#define SDL_JOYSTICK_LINUX 1" >>confdefs.h $as_echo "#define SDL_JOYSTICK_ANDROID 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/joystick/android/*.c" + SOURCES="$SOURCES $srcdir/src/joystick/steam/*.c" have_joystick=yes ;; esac @@ -24244,6 +24245,7 @@ $as_echo "#define SDL_AUDIO_DRIVER_COREAUDIO 1" >>confdefs.h $as_echo "#define SDL_JOYSTICK_MFI 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/joystick/iphoneos/*.m" + SOURCES="$SOURCES $srcdir/src/joystick/steam/*.c" have_joystick=yes fi # Set up files for the haptic library diff --git a/configure.in b/configure.in index 0feb0ebe07..33572d7a15 100644 --- a/configure.in +++ b/configure.in @@ -3366,6 +3366,7 @@ case "$host" in android) AC_DEFINE(SDL_JOYSTICK_ANDROID, 1, [ ]) SOURCES="$SOURCES $srcdir/src/joystick/android/*.c" + SOURCES="$SOURCES $srcdir/src/joystick/steam/*.c" have_joystick=yes ;; esac @@ -3645,6 +3646,7 @@ AC_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau if test x$enable_joystick = xyes; then AC_DEFINE(SDL_JOYSTICK_MFI, 1, [ ]) SOURCES="$SOURCES $srcdir/src/joystick/iphoneos/*.m" + SOURCES="$SOURCES $srcdir/src/joystick/steam/*.c" have_joystick=yes fi # Set up files for the haptic library From e1c48179b8df6886dfb7ac58f05aae1d59e82fcc Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 22 Sep 2017 17:02:18 -0700 Subject: [PATCH 13/95] Good bye, Visual Studio 2008 --- VisualC/SDL/SDL_VS2008.vcproj | 1543 ----------------- VisualC/SDL_VS2008.sln | 280 --- VisualC/SDLmain/SDLmain_VS2008.vcproj | 294 ---- VisualC/SDLtest/SDLtest_VS2008.vcproj | 350 ---- .../tests/checkkeys/checkkeys_VS2008.vcproj | 388 ----- .../controllermap/controllermap_VS2008.vcproj | 480 ----- VisualC/tests/loopwave/loopwave_VS2008.vcproj | 396 ----- .../tests/testatomic/testatomic_VS2008.vcproj | 348 ---- .../testautomation_VS2008.vcproj | 431 ----- .../tests/testdraw2/testdraw2_VS2008.vcproj | 355 ---- VisualC/tests/testfile/testfile_VS2008.vcproj | 348 ---- .../testgamecontroller_VS2008.vcproj | 480 ----- .../testgesture/testgesture_VS2008.vcproj | 348 ---- VisualC/tests/testgl2/testgl2_VS2008.vcproj | 359 ---- .../tests/testgles2/testgles2_VS2008.vcproj | 352 ---- .../testjoystick/testjoystick_VS2008.vcproj | 348 ---- .../testoverlay2/testoverlay2_VS2008.vcproj | 392 ----- .../testplatform/testplatform_VS2008.vcproj | 364 ---- .../tests/testpower/testpower_VS2008.vcproj | 348 ---- .../testrendertarget_VS2008.vcproj | 443 ----- .../tests/testrumble/testrumble_VS2008.vcproj | 348 ---- .../tests/testscale/testscale_VS2008.vcproj | 443 ----- .../tests/testshape/testshape_VS2008.vcproj | 348 ---- .../testsprite2/testsprite2_VS2008.vcproj | 399 ----- .../tests/testvulkan/testvulkan_VS2008.vcproj | 355 ---- 25 files changed, 10540 deletions(-) delete mode 100644 VisualC/SDL/SDL_VS2008.vcproj delete mode 100644 VisualC/SDL_VS2008.sln delete mode 100644 VisualC/SDLmain/SDLmain_VS2008.vcproj delete mode 100644 VisualC/SDLtest/SDLtest_VS2008.vcproj delete mode 100644 VisualC/tests/checkkeys/checkkeys_VS2008.vcproj delete mode 100644 VisualC/tests/controllermap/controllermap_VS2008.vcproj delete mode 100644 VisualC/tests/loopwave/loopwave_VS2008.vcproj delete mode 100644 VisualC/tests/testatomic/testatomic_VS2008.vcproj delete mode 100755 VisualC/tests/testautomation/testautomation_VS2008.vcproj delete mode 100644 VisualC/tests/testdraw2/testdraw2_VS2008.vcproj delete mode 100644 VisualC/tests/testfile/testfile_VS2008.vcproj delete mode 100644 VisualC/tests/testgamecontroller/testgamecontroller_VS2008.vcproj delete mode 100644 VisualC/tests/testgesture/testgesture_VS2008.vcproj delete mode 100644 VisualC/tests/testgl2/testgl2_VS2008.vcproj delete mode 100644 VisualC/tests/testgles2/testgles2_VS2008.vcproj delete mode 100644 VisualC/tests/testjoystick/testjoystick_VS2008.vcproj delete mode 100644 VisualC/tests/testoverlay2/testoverlay2_VS2008.vcproj delete mode 100644 VisualC/tests/testplatform/testplatform_VS2008.vcproj delete mode 100644 VisualC/tests/testpower/testpower_VS2008.vcproj delete mode 100644 VisualC/tests/testrendertarget/testrendertarget_VS2008.vcproj delete mode 100644 VisualC/tests/testrumble/testrumble_VS2008.vcproj delete mode 100644 VisualC/tests/testscale/testscale_VS2008.vcproj delete mode 100644 VisualC/tests/testshape/testshape_VS2008.vcproj delete mode 100644 VisualC/tests/testsprite2/testsprite2_VS2008.vcproj delete mode 100644 VisualC/tests/testvulkan/testvulkan_VS2008.vcproj diff --git a/VisualC/SDL/SDL_VS2008.vcproj b/VisualC/SDL/SDL_VS2008.vcproj deleted file mode 100644 index e4ecdc0c17..0000000000 --- a/VisualC/SDL/SDL_VS2008.vcproj +++ /dev/null @@ -1,1543 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/VisualC/SDL_VS2008.sln b/VisualC/SDL_VS2008.sln deleted file mode 100644 index 83c3ccf779..0000000000 --- a/VisualC/SDL_VS2008.sln +++ /dev/null @@ -1,280 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 10.00 -# Visual Studio 2008 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SDL2", "SDL\SDL_VS2008.vcproj", "{81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SDL2main", "SDLmain\SDLmain_VS2008.vcproj", "{DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "checkkeys", "tests\checkkeys\checkkeys_VS2008.vcproj", "{26828762-C95D-4637-9CB1-7F0979523813}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "loopwave", "tests\loopwave\loopwave_VS2008.vcproj", "{AAAD1CB5-7ADA-47AE-85A0-08A6EC48FAFB}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testatomic", "tests\testatomic\testatomic_VS2008.vcproj", "{66B32F7E-5716-48D0-B5B9-D832FD052DD5}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testautomation", "tests\testautomation\testautomation_VS2008.vcproj", "{9C7E8C03-3130-436D-A97E-E8F8ED1AC4EA}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testdraw2", "tests\testdraw2\testdraw2_VS2008.vcproj", "{8682FE1E-0CF6-4EDD-9BB5-1733D8C8B4DF}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testfile", "tests\testfile\testfile_VS2008.vcproj", "{CAE4F1D0-314F-4B10-805B-0EFD670133A0}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testgesture", "tests\testgesture\testgesture_VS2008.vcproj", "{79CEE57E-1BC3-4FF6-90B3-9E39763CDAFF}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testgl2", "tests\testgl2\testgl2_VS2008.vcproj", "{8B5CFB38-CCBA-40A8-AD7A-89C57B070884}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testjoystick", "tests\testjoystick\testjoystick_VS2008.vcproj", "{55812185-D13C-4022-9C81-32E0F4A08304}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testoverlay2", "tests\testoverlay2\testoverlay2_VS2008.vcproj", "{B51E0D74-F0A2-45A2-BD2A-8B7D95B8204A}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testplatform", "tests\testplatform\testplatform_VS2008.vcproj", "{26932B24-EFC6-4E3A-B277-ED653DA37968}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testpower", "tests\testpower\testpower_VS2008.vcproj", "{C4E04D18-EF76-4B42-B4C2-16A1BACDC0A3}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testrendertarget", "tests\testrendertarget\testrendertarget_VS2008.vcproj", "{2D17C1EB-1157-460E-9A99-A82BFC1F9D1E}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testrumble", "tests\testrumble\testrumble_VS2008.vcproj", "{BFF40245-E9A6-4297-A425-A554E5D767E8}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testscale", "tests\testscale\testscale_VS2008.vcproj", "{5D0930C0-7C91-4ECE-9014-7B7DDE9502E6}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testshape", "tests\testshape\testshape_VS2008.vcproj", "{31A3E4E1-AAE9-4EF3-9B23-18D0924BE4D2}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testsprite2", "tests\testsprite2\testsprite2_VS2008.vcproj", "{40FB7794-D3C3-4CFE-BCF4-A80C96635682}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SDL2test", "SDLtest\SDLtest_VS2008.vcproj", "{DA956FD3-E143-46F2-9FE5-C77BEBC56B1A}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testgamecontroller", "tests\testgamecontroller\testgamecontroller_VS2008.vcproj", "{55812185-D13C-4022-9C81-32E0F4A08305}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testgles2", "tests\testgles2\testgles2_VS2008.vcproj", "{E9558DFE-1961-4DD4-B09B-DD0EEFD5C315}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "controllermap", "tests\controllermap\controllermap_VS2008.vcproj", "{55812185-D13C-4022-9C81-32E0F4A08306}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{D69D5741-611F-4E14-8541-1FEE94F50B5A}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testvulkan", "tests\testvulkan\testvulkan_VS2008.vcproj", "{0D604DFD-AAB6-442C-9368-F91A344146AB}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Debug|Win32.ActiveCfg = Debug|Win32 - {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Debug|Win32.Build.0 = Debug|Win32 - {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Debug|x64.ActiveCfg = Debug|x64 - {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Debug|x64.Build.0 = Debug|x64 - {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release|Win32.ActiveCfg = Release|Win32 - {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release|Win32.Build.0 = Release|Win32 - {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release|x64.ActiveCfg = Release|x64 - {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release|x64.Build.0 = Release|x64 - {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Debug|Win32.ActiveCfg = Debug|Win32 - {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Debug|Win32.Build.0 = Debug|Win32 - {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Debug|x64.ActiveCfg = Debug|x64 - {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Debug|x64.Build.0 = Debug|x64 - {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Release|Win32.ActiveCfg = Release|Win32 - {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Release|Win32.Build.0 = Release|Win32 - {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Release|x64.ActiveCfg = Release|x64 - {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Release|x64.Build.0 = Release|x64 - {26828762-C95D-4637-9CB1-7F0979523813}.Debug|Win32.ActiveCfg = Debug|Win32 - {26828762-C95D-4637-9CB1-7F0979523813}.Debug|Win32.Build.0 = Debug|Win32 - {26828762-C95D-4637-9CB1-7F0979523813}.Debug|x64.ActiveCfg = Debug|x64 - {26828762-C95D-4637-9CB1-7F0979523813}.Debug|x64.Build.0 = Debug|x64 - {26828762-C95D-4637-9CB1-7F0979523813}.Release|Win32.ActiveCfg = Release|Win32 - {26828762-C95D-4637-9CB1-7F0979523813}.Release|Win32.Build.0 = Release|Win32 - {26828762-C95D-4637-9CB1-7F0979523813}.Release|x64.ActiveCfg = Release|x64 - {26828762-C95D-4637-9CB1-7F0979523813}.Release|x64.Build.0 = Release|x64 - {AAAD1CB5-7ADA-47AE-85A0-08A6EC48FAFB}.Debug|Win32.ActiveCfg = Debug|Win32 - {AAAD1CB5-7ADA-47AE-85A0-08A6EC48FAFB}.Debug|Win32.Build.0 = Debug|Win32 - {AAAD1CB5-7ADA-47AE-85A0-08A6EC48FAFB}.Debug|x64.ActiveCfg = Debug|x64 - {AAAD1CB5-7ADA-47AE-85A0-08A6EC48FAFB}.Debug|x64.Build.0 = Debug|x64 - {AAAD1CB5-7ADA-47AE-85A0-08A6EC48FAFB}.Release|Win32.ActiveCfg = Release|Win32 - {AAAD1CB5-7ADA-47AE-85A0-08A6EC48FAFB}.Release|Win32.Build.0 = Release|Win32 - {AAAD1CB5-7ADA-47AE-85A0-08A6EC48FAFB}.Release|x64.ActiveCfg = Release|x64 - {AAAD1CB5-7ADA-47AE-85A0-08A6EC48FAFB}.Release|x64.Build.0 = Release|x64 - {66B32F7E-5716-48D0-B5B9-D832FD052DD5}.Debug|Win32.ActiveCfg = Debug|Win32 - {66B32F7E-5716-48D0-B5B9-D832FD052DD5}.Debug|Win32.Build.0 = Debug|Win32 - {66B32F7E-5716-48D0-B5B9-D832FD052DD5}.Debug|x64.ActiveCfg = Debug|x64 - {66B32F7E-5716-48D0-B5B9-D832FD052DD5}.Debug|x64.Build.0 = Debug|x64 - {66B32F7E-5716-48D0-B5B9-D832FD052DD5}.Release|Win32.ActiveCfg = Release|Win32 - {66B32F7E-5716-48D0-B5B9-D832FD052DD5}.Release|Win32.Build.0 = Release|Win32 - {66B32F7E-5716-48D0-B5B9-D832FD052DD5}.Release|x64.ActiveCfg = Release|x64 - {66B32F7E-5716-48D0-B5B9-D832FD052DD5}.Release|x64.Build.0 = Release|x64 - {9C7E8C03-3130-436D-A97E-E8F8ED1AC4EA}.Debug|Win32.ActiveCfg = Debug|Win32 - {9C7E8C03-3130-436D-A97E-E8F8ED1AC4EA}.Debug|Win32.Build.0 = Debug|Win32 - {9C7E8C03-3130-436D-A97E-E8F8ED1AC4EA}.Debug|x64.ActiveCfg = Debug|x64 - {9C7E8C03-3130-436D-A97E-E8F8ED1AC4EA}.Debug|x64.Build.0 = Debug|x64 - {9C7E8C03-3130-436D-A97E-E8F8ED1AC4EA}.Release|Win32.ActiveCfg = Release|Win32 - {9C7E8C03-3130-436D-A97E-E8F8ED1AC4EA}.Release|Win32.Build.0 = Release|Win32 - {9C7E8C03-3130-436D-A97E-E8F8ED1AC4EA}.Release|x64.ActiveCfg = Release|x64 - {9C7E8C03-3130-436D-A97E-E8F8ED1AC4EA}.Release|x64.Build.0 = Release|x64 - {8682FE1E-0CF6-4EDD-9BB5-1733D8C8B4DF}.Debug|Win32.ActiveCfg = Debug|Win32 - {8682FE1E-0CF6-4EDD-9BB5-1733D8C8B4DF}.Debug|Win32.Build.0 = Debug|Win32 - {8682FE1E-0CF6-4EDD-9BB5-1733D8C8B4DF}.Debug|x64.ActiveCfg = Debug|x64 - {8682FE1E-0CF6-4EDD-9BB5-1733D8C8B4DF}.Debug|x64.Build.0 = Debug|x64 - {8682FE1E-0CF6-4EDD-9BB5-1733D8C8B4DF}.Release|Win32.ActiveCfg = Release|Win32 - {8682FE1E-0CF6-4EDD-9BB5-1733D8C8B4DF}.Release|Win32.Build.0 = Release|Win32 - {8682FE1E-0CF6-4EDD-9BB5-1733D8C8B4DF}.Release|x64.ActiveCfg = Release|x64 - {8682FE1E-0CF6-4EDD-9BB5-1733D8C8B4DF}.Release|x64.Build.0 = Release|x64 - {CAE4F1D0-314F-4B10-805B-0EFD670133A0}.Debug|Win32.ActiveCfg = Debug|Win32 - {CAE4F1D0-314F-4B10-805B-0EFD670133A0}.Debug|Win32.Build.0 = Debug|Win32 - {CAE4F1D0-314F-4B10-805B-0EFD670133A0}.Debug|x64.ActiveCfg = Debug|x64 - {CAE4F1D0-314F-4B10-805B-0EFD670133A0}.Debug|x64.Build.0 = Debug|x64 - {CAE4F1D0-314F-4B10-805B-0EFD670133A0}.Release|Win32.ActiveCfg = Release|Win32 - {CAE4F1D0-314F-4B10-805B-0EFD670133A0}.Release|Win32.Build.0 = Release|Win32 - {CAE4F1D0-314F-4B10-805B-0EFD670133A0}.Release|x64.ActiveCfg = Release|x64 - {CAE4F1D0-314F-4B10-805B-0EFD670133A0}.Release|x64.Build.0 = Release|x64 - {79CEE57E-1BC3-4FF6-90B3-9E39763CDAFF}.Debug|Win32.ActiveCfg = Debug|Win32 - {79CEE57E-1BC3-4FF6-90B3-9E39763CDAFF}.Debug|Win32.Build.0 = Debug|Win32 - {79CEE57E-1BC3-4FF6-90B3-9E39763CDAFF}.Debug|x64.ActiveCfg = Debug|x64 - {79CEE57E-1BC3-4FF6-90B3-9E39763CDAFF}.Debug|x64.Build.0 = Debug|x64 - {79CEE57E-1BC3-4FF6-90B3-9E39763CDAFF}.Release|Win32.ActiveCfg = Release|Win32 - {79CEE57E-1BC3-4FF6-90B3-9E39763CDAFF}.Release|Win32.Build.0 = Release|Win32 - {79CEE57E-1BC3-4FF6-90B3-9E39763CDAFF}.Release|x64.ActiveCfg = Release|x64 - {79CEE57E-1BC3-4FF6-90B3-9E39763CDAFF}.Release|x64.Build.0 = Release|x64 - {8B5CFB38-CCBA-40A8-AD7A-89C57B070884}.Debug|Win32.ActiveCfg = Debug|Win32 - {8B5CFB38-CCBA-40A8-AD7A-89C57B070884}.Debug|Win32.Build.0 = Debug|Win32 - {8B5CFB38-CCBA-40A8-AD7A-89C57B070884}.Debug|x64.ActiveCfg = Debug|x64 - {8B5CFB38-CCBA-40A8-AD7A-89C57B070884}.Debug|x64.Build.0 = Debug|x64 - {8B5CFB38-CCBA-40A8-AD7A-89C57B070884}.Release|Win32.ActiveCfg = Release|Win32 - {8B5CFB38-CCBA-40A8-AD7A-89C57B070884}.Release|Win32.Build.0 = Release|Win32 - {8B5CFB38-CCBA-40A8-AD7A-89C57B070884}.Release|x64.ActiveCfg = Release|x64 - {8B5CFB38-CCBA-40A8-AD7A-89C57B070884}.Release|x64.Build.0 = Release|x64 - {55812185-D13C-4022-9C81-32E0F4A08304}.Debug|Win32.ActiveCfg = Debug|Win32 - {55812185-D13C-4022-9C81-32E0F4A08304}.Debug|Win32.Build.0 = Debug|Win32 - {55812185-D13C-4022-9C81-32E0F4A08304}.Debug|x64.ActiveCfg = Debug|x64 - {55812185-D13C-4022-9C81-32E0F4A08304}.Debug|x64.Build.0 = Debug|x64 - {55812185-D13C-4022-9C81-32E0F4A08304}.Release|Win32.ActiveCfg = Release|Win32 - {55812185-D13C-4022-9C81-32E0F4A08304}.Release|Win32.Build.0 = Release|Win32 - {55812185-D13C-4022-9C81-32E0F4A08304}.Release|x64.ActiveCfg = Release|x64 - {55812185-D13C-4022-9C81-32E0F4A08304}.Release|x64.Build.0 = Release|x64 - {B51E0D74-F0A2-45A2-BD2A-8B7D95B8204A}.Debug|Win32.ActiveCfg = Debug|Win32 - {B51E0D74-F0A2-45A2-BD2A-8B7D95B8204A}.Debug|Win32.Build.0 = Debug|Win32 - {B51E0D74-F0A2-45A2-BD2A-8B7D95B8204A}.Debug|x64.ActiveCfg = Debug|x64 - {B51E0D74-F0A2-45A2-BD2A-8B7D95B8204A}.Debug|x64.Build.0 = Debug|x64 - {B51E0D74-F0A2-45A2-BD2A-8B7D95B8204A}.Release|Win32.ActiveCfg = Release|Win32 - {B51E0D74-F0A2-45A2-BD2A-8B7D95B8204A}.Release|Win32.Build.0 = Release|Win32 - {B51E0D74-F0A2-45A2-BD2A-8B7D95B8204A}.Release|x64.ActiveCfg = Release|x64 - {B51E0D74-F0A2-45A2-BD2A-8B7D95B8204A}.Release|x64.Build.0 = Release|x64 - {26932B24-EFC6-4E3A-B277-ED653DA37968}.Debug|Win32.ActiveCfg = Debug|Win32 - {26932B24-EFC6-4E3A-B277-ED653DA37968}.Debug|Win32.Build.0 = Debug|Win32 - {26932B24-EFC6-4E3A-B277-ED653DA37968}.Debug|x64.ActiveCfg = Debug|x64 - {26932B24-EFC6-4E3A-B277-ED653DA37968}.Debug|x64.Build.0 = Debug|x64 - {26932B24-EFC6-4E3A-B277-ED653DA37968}.Release|Win32.ActiveCfg = Release|Win32 - {26932B24-EFC6-4E3A-B277-ED653DA37968}.Release|Win32.Build.0 = Release|Win32 - {26932B24-EFC6-4E3A-B277-ED653DA37968}.Release|x64.ActiveCfg = Release|x64 - {26932B24-EFC6-4E3A-B277-ED653DA37968}.Release|x64.Build.0 = Release|x64 - {C4E04D18-EF76-4B42-B4C2-16A1BACDC0A3}.Debug|Win32.ActiveCfg = Debug|Win32 - {C4E04D18-EF76-4B42-B4C2-16A1BACDC0A3}.Debug|Win32.Build.0 = Debug|Win32 - {C4E04D18-EF76-4B42-B4C2-16A1BACDC0A3}.Debug|x64.ActiveCfg = Debug|x64 - {C4E04D18-EF76-4B42-B4C2-16A1BACDC0A3}.Debug|x64.Build.0 = Debug|x64 - {C4E04D18-EF76-4B42-B4C2-16A1BACDC0A3}.Release|Win32.ActiveCfg = Release|Win32 - {C4E04D18-EF76-4B42-B4C2-16A1BACDC0A3}.Release|Win32.Build.0 = Release|Win32 - {C4E04D18-EF76-4B42-B4C2-16A1BACDC0A3}.Release|x64.ActiveCfg = Release|x64 - {C4E04D18-EF76-4B42-B4C2-16A1BACDC0A3}.Release|x64.Build.0 = Release|x64 - {2D17C1EB-1157-460E-9A99-A82BFC1F9D1E}.Debug|Win32.ActiveCfg = Debug|Win32 - {2D17C1EB-1157-460E-9A99-A82BFC1F9D1E}.Debug|Win32.Build.0 = Debug|Win32 - {2D17C1EB-1157-460E-9A99-A82BFC1F9D1E}.Debug|x64.ActiveCfg = Debug|x64 - {2D17C1EB-1157-460E-9A99-A82BFC1F9D1E}.Debug|x64.Build.0 = Debug|x64 - {2D17C1EB-1157-460E-9A99-A82BFC1F9D1E}.Release|Win32.ActiveCfg = Release|Win32 - {2D17C1EB-1157-460E-9A99-A82BFC1F9D1E}.Release|Win32.Build.0 = Release|Win32 - {2D17C1EB-1157-460E-9A99-A82BFC1F9D1E}.Release|x64.ActiveCfg = Release|x64 - {2D17C1EB-1157-460E-9A99-A82BFC1F9D1E}.Release|x64.Build.0 = Release|x64 - {BFF40245-E9A6-4297-A425-A554E5D767E8}.Debug|Win32.ActiveCfg = Debug|Win32 - {BFF40245-E9A6-4297-A425-A554E5D767E8}.Debug|Win32.Build.0 = Debug|Win32 - {BFF40245-E9A6-4297-A425-A554E5D767E8}.Debug|x64.ActiveCfg = Debug|x64 - {BFF40245-E9A6-4297-A425-A554E5D767E8}.Debug|x64.Build.0 = Debug|x64 - {BFF40245-E9A6-4297-A425-A554E5D767E8}.Release|Win32.ActiveCfg = Release|Win32 - {BFF40245-E9A6-4297-A425-A554E5D767E8}.Release|Win32.Build.0 = Release|Win32 - {BFF40245-E9A6-4297-A425-A554E5D767E8}.Release|x64.ActiveCfg = Release|x64 - {BFF40245-E9A6-4297-A425-A554E5D767E8}.Release|x64.Build.0 = Release|x64 - {5D0930C0-7C91-4ECE-9014-7B7DDE9502E6}.Debug|Win32.ActiveCfg = Debug|Win32 - {5D0930C0-7C91-4ECE-9014-7B7DDE9502E6}.Debug|Win32.Build.0 = Debug|Win32 - {5D0930C0-7C91-4ECE-9014-7B7DDE9502E6}.Debug|x64.ActiveCfg = Debug|x64 - {5D0930C0-7C91-4ECE-9014-7B7DDE9502E6}.Debug|x64.Build.0 = Debug|x64 - {5D0930C0-7C91-4ECE-9014-7B7DDE9502E6}.Release|Win32.ActiveCfg = Release|Win32 - {5D0930C0-7C91-4ECE-9014-7B7DDE9502E6}.Release|Win32.Build.0 = Release|Win32 - {5D0930C0-7C91-4ECE-9014-7B7DDE9502E6}.Release|x64.ActiveCfg = Release|x64 - {5D0930C0-7C91-4ECE-9014-7B7DDE9502E6}.Release|x64.Build.0 = Release|x64 - {31A3E4E1-AAE9-4EF3-9B23-18D0924BE4D2}.Debug|Win32.ActiveCfg = Debug|Win32 - {31A3E4E1-AAE9-4EF3-9B23-18D0924BE4D2}.Debug|Win32.Build.0 = Debug|Win32 - {31A3E4E1-AAE9-4EF3-9B23-18D0924BE4D2}.Debug|x64.ActiveCfg = Debug|x64 - {31A3E4E1-AAE9-4EF3-9B23-18D0924BE4D2}.Debug|x64.Build.0 = Debug|x64 - {31A3E4E1-AAE9-4EF3-9B23-18D0924BE4D2}.Release|Win32.ActiveCfg = Release|Win32 - {31A3E4E1-AAE9-4EF3-9B23-18D0924BE4D2}.Release|Win32.Build.0 = Release|Win32 - {31A3E4E1-AAE9-4EF3-9B23-18D0924BE4D2}.Release|x64.ActiveCfg = Release|x64 - {31A3E4E1-AAE9-4EF3-9B23-18D0924BE4D2}.Release|x64.Build.0 = Release|x64 - {40FB7794-D3C3-4CFE-BCF4-A80C96635682}.Debug|Win32.ActiveCfg = Debug|Win32 - {40FB7794-D3C3-4CFE-BCF4-A80C96635682}.Debug|Win32.Build.0 = Debug|Win32 - {40FB7794-D3C3-4CFE-BCF4-A80C96635682}.Debug|x64.ActiveCfg = Debug|x64 - {40FB7794-D3C3-4CFE-BCF4-A80C96635682}.Debug|x64.Build.0 = Debug|x64 - {40FB7794-D3C3-4CFE-BCF4-A80C96635682}.Release|Win32.ActiveCfg = Release|Win32 - {40FB7794-D3C3-4CFE-BCF4-A80C96635682}.Release|Win32.Build.0 = Release|Win32 - {40FB7794-D3C3-4CFE-BCF4-A80C96635682}.Release|x64.ActiveCfg = Release|x64 - {40FB7794-D3C3-4CFE-BCF4-A80C96635682}.Release|x64.Build.0 = Release|x64 - {DA956FD3-E143-46F2-9FE5-C77BEBC56B1A}.Debug|Win32.ActiveCfg = Debug|Win32 - {DA956FD3-E143-46F2-9FE5-C77BEBC56B1A}.Debug|Win32.Build.0 = Debug|Win32 - {DA956FD3-E143-46F2-9FE5-C77BEBC56B1A}.Debug|x64.ActiveCfg = Debug|x64 - {DA956FD3-E143-46F2-9FE5-C77BEBC56B1A}.Debug|x64.Build.0 = Debug|x64 - {DA956FD3-E143-46F2-9FE5-C77BEBC56B1A}.Release|Win32.ActiveCfg = Release|Win32 - {DA956FD3-E143-46F2-9FE5-C77BEBC56B1A}.Release|Win32.Build.0 = Release|Win32 - {DA956FD3-E143-46F2-9FE5-C77BEBC56B1A}.Release|x64.ActiveCfg = Release|x64 - {DA956FD3-E143-46F2-9FE5-C77BEBC56B1A}.Release|x64.Build.0 = Release|x64 - {55812185-D13C-4022-9C81-32E0F4A08305}.Debug|Win32.ActiveCfg = Debug|Win32 - {55812185-D13C-4022-9C81-32E0F4A08305}.Debug|Win32.Build.0 = Debug|Win32 - {55812185-D13C-4022-9C81-32E0F4A08305}.Debug|x64.ActiveCfg = Debug|x64 - {55812185-D13C-4022-9C81-32E0F4A08305}.Debug|x64.Build.0 = Debug|x64 - {55812185-D13C-4022-9C81-32E0F4A08305}.Release|Win32.ActiveCfg = Release|Win32 - {55812185-D13C-4022-9C81-32E0F4A08305}.Release|Win32.Build.0 = Release|Win32 - {55812185-D13C-4022-9C81-32E0F4A08305}.Release|x64.ActiveCfg = Release|x64 - {55812185-D13C-4022-9C81-32E0F4A08305}.Release|x64.Build.0 = Release|x64 - {E9558DFE-1961-4DD4-B09B-DD0EEFD5C315}.Debug|Win32.ActiveCfg = Debug|Win32 - {E9558DFE-1961-4DD4-B09B-DD0EEFD5C315}.Debug|Win32.Build.0 = Debug|Win32 - {E9558DFE-1961-4DD4-B09B-DD0EEFD5C315}.Debug|x64.ActiveCfg = Debug|x64 - {E9558DFE-1961-4DD4-B09B-DD0EEFD5C315}.Debug|x64.Build.0 = Debug|x64 - {E9558DFE-1961-4DD4-B09B-DD0EEFD5C315}.Release|Win32.ActiveCfg = Release|Win32 - {E9558DFE-1961-4DD4-B09B-DD0EEFD5C315}.Release|Win32.Build.0 = Release|Win32 - {E9558DFE-1961-4DD4-B09B-DD0EEFD5C315}.Release|x64.ActiveCfg = Release|x64 - {E9558DFE-1961-4DD4-B09B-DD0EEFD5C315}.Release|x64.Build.0 = Release|x64 - {55812185-D13C-4022-9C81-32E0F4A08306}.Debug|Win32.ActiveCfg = Debug|Win32 - {55812185-D13C-4022-9C81-32E0F4A08306}.Debug|Win32.Build.0 = Debug|Win32 - {55812185-D13C-4022-9C81-32E0F4A08306}.Debug|x64.ActiveCfg = Debug|x64 - {55812185-D13C-4022-9C81-32E0F4A08306}.Debug|x64.Build.0 = Debug|x64 - {55812185-D13C-4022-9C81-32E0F4A08306}.Release|Win32.ActiveCfg = Release|Win32 - {55812185-D13C-4022-9C81-32E0F4A08306}.Release|Win32.Build.0 = Release|Win32 - {55812185-D13C-4022-9C81-32E0F4A08306}.Release|x64.ActiveCfg = Release|x64 - {55812185-D13C-4022-9C81-32E0F4A08306}.Release|x64.Build.0 = Release|x64 - {0D604DFD-AAB6-442C-9368-F91A344146AB}.Debug|Win32.ActiveCfg = Debug|Win32 - {0D604DFD-AAB6-442C-9368-F91A344146AB}.Debug|Win32.Build.0 = Debug|Win32 - {0D604DFD-AAB6-442C-9368-F91A344146AB}.Debug|x64.ActiveCfg = Debug|x64 - {0D604DFD-AAB6-442C-9368-F91A344146AB}.Debug|x64.Build.0 = Debug|x64 - {0D604DFD-AAB6-442C-9368-F91A344146AB}.Release|Win32.ActiveCfg = Release|Win32 - {0D604DFD-AAB6-442C-9368-F91A344146AB}.Release|Win32.Build.0 = Release|Win32 - {0D604DFD-AAB6-442C-9368-F91A344146AB}.Release|x64.ActiveCfg = Release|x64 - {0D604DFD-AAB6-442C-9368-F91A344146AB}.Release|x64.Build.0 = Release|x64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {AAAD1CB5-7ADA-47AE-85A0-08A6EC48FAFB} = {D69D5741-611F-4E14-8541-1FEE94F50B5A} - {66B32F7E-5716-48D0-B5B9-D832FD052DD5} = {D69D5741-611F-4E14-8541-1FEE94F50B5A} - {9C7E8C03-3130-436D-A97E-E8F8ED1AC4EA} = {D69D5741-611F-4E14-8541-1FEE94F50B5A} - {8682FE1E-0CF6-4EDD-9BB5-1733D8C8B4DF} = {D69D5741-611F-4E14-8541-1FEE94F50B5A} - {CAE4F1D0-314F-4B10-805B-0EFD670133A0} = {D69D5741-611F-4E14-8541-1FEE94F50B5A} - {79CEE57E-1BC3-4FF6-90B3-9E39763CDAFF} = {D69D5741-611F-4E14-8541-1FEE94F50B5A} - {8B5CFB38-CCBA-40A8-AD7A-89C57B070884} = {D69D5741-611F-4E14-8541-1FEE94F50B5A} - {55812185-D13C-4022-9C81-32E0F4A08304} = {D69D5741-611F-4E14-8541-1FEE94F50B5A} - {B51E0D74-F0A2-45A2-BD2A-8B7D95B8204A} = {D69D5741-611F-4E14-8541-1FEE94F50B5A} - {26932B24-EFC6-4E3A-B277-ED653DA37968} = {D69D5741-611F-4E14-8541-1FEE94F50B5A} - {C4E04D18-EF76-4B42-B4C2-16A1BACDC0A3} = {D69D5741-611F-4E14-8541-1FEE94F50B5A} - {2D17C1EB-1157-460E-9A99-A82BFC1F9D1E} = {D69D5741-611F-4E14-8541-1FEE94F50B5A} - {BFF40245-E9A6-4297-A425-A554E5D767E8} = {D69D5741-611F-4E14-8541-1FEE94F50B5A} - {5D0930C0-7C91-4ECE-9014-7B7DDE9502E6} = {D69D5741-611F-4E14-8541-1FEE94F50B5A} - {31A3E4E1-AAE9-4EF3-9B23-18D0924BE4D2} = {D69D5741-611F-4E14-8541-1FEE94F50B5A} - {40FB7794-D3C3-4CFE-BCF4-A80C96635682} = {D69D5741-611F-4E14-8541-1FEE94F50B5A} - {55812185-D13C-4022-9C81-32E0F4A08305} = {D69D5741-611F-4E14-8541-1FEE94F50B5A} - {E9558DFE-1961-4DD4-B09B-DD0EEFD5C315} = {D69D5741-611F-4E14-8541-1FEE94F50B5A} - {55812185-D13C-4022-9C81-32E0F4A08306} = {D69D5741-611F-4E14-8541-1FEE94F50B5A} - {26828762-C95D-4637-9CB1-7F0979523813} = {D69D5741-611F-4E14-8541-1FEE94F50B5A} - {0D604DFD-AAB6-442C-9368-F91A344146AB} = {D69D5741-611F-4E14-8541-1FEE94F50B5A} - EndGlobalSection -EndGlobal diff --git a/VisualC/SDLmain/SDLmain_VS2008.vcproj b/VisualC/SDLmain/SDLmain_VS2008.vcproj deleted file mode 100644 index 354bf536c7..0000000000 --- a/VisualC/SDLmain/SDLmain_VS2008.vcproj +++ /dev/null @@ -1,294 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/VisualC/SDLtest/SDLtest_VS2008.vcproj b/VisualC/SDLtest/SDLtest_VS2008.vcproj deleted file mode 100644 index 8b9074794c..0000000000 --- a/VisualC/SDLtest/SDLtest_VS2008.vcproj +++ /dev/null @@ -1,350 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/VisualC/tests/checkkeys/checkkeys_VS2008.vcproj b/VisualC/tests/checkkeys/checkkeys_VS2008.vcproj deleted file mode 100644 index b02c4cfa7d..0000000000 --- a/VisualC/tests/checkkeys/checkkeys_VS2008.vcproj +++ /dev/null @@ -1,388 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/VisualC/tests/controllermap/controllermap_VS2008.vcproj b/VisualC/tests/controllermap/controllermap_VS2008.vcproj deleted file mode 100644 index 1ecce67373..0000000000 --- a/VisualC/tests/controllermap/controllermap_VS2008.vcproj +++ /dev/null @@ -1,480 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/VisualC/tests/loopwave/loopwave_VS2008.vcproj b/VisualC/tests/loopwave/loopwave_VS2008.vcproj deleted file mode 100644 index 1cbf89a8cd..0000000000 --- a/VisualC/tests/loopwave/loopwave_VS2008.vcproj +++ /dev/null @@ -1,396 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/VisualC/tests/testatomic/testatomic_VS2008.vcproj b/VisualC/tests/testatomic/testatomic_VS2008.vcproj deleted file mode 100644 index 5f4452b580..0000000000 --- a/VisualC/tests/testatomic/testatomic_VS2008.vcproj +++ /dev/null @@ -1,348 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/VisualC/tests/testautomation/testautomation_VS2008.vcproj b/VisualC/tests/testautomation/testautomation_VS2008.vcproj deleted file mode 100755 index dc1bec0f44..0000000000 --- a/VisualC/tests/testautomation/testautomation_VS2008.vcproj +++ /dev/null @@ -1,431 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/VisualC/tests/testdraw2/testdraw2_VS2008.vcproj b/VisualC/tests/testdraw2/testdraw2_VS2008.vcproj deleted file mode 100644 index 16612aeaac..0000000000 --- a/VisualC/tests/testdraw2/testdraw2_VS2008.vcproj +++ /dev/null @@ -1,355 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/VisualC/tests/testfile/testfile_VS2008.vcproj b/VisualC/tests/testfile/testfile_VS2008.vcproj deleted file mode 100644 index 46f796a4a1..0000000000 --- a/VisualC/tests/testfile/testfile_VS2008.vcproj +++ /dev/null @@ -1,348 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/VisualC/tests/testgamecontroller/testgamecontroller_VS2008.vcproj b/VisualC/tests/testgamecontroller/testgamecontroller_VS2008.vcproj deleted file mode 100644 index 1b31f57b0a..0000000000 --- a/VisualC/tests/testgamecontroller/testgamecontroller_VS2008.vcproj +++ /dev/null @@ -1,480 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/VisualC/tests/testgesture/testgesture_VS2008.vcproj b/VisualC/tests/testgesture/testgesture_VS2008.vcproj deleted file mode 100644 index 4fff2273ea..0000000000 --- a/VisualC/tests/testgesture/testgesture_VS2008.vcproj +++ /dev/null @@ -1,348 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/VisualC/tests/testgl2/testgl2_VS2008.vcproj b/VisualC/tests/testgl2/testgl2_VS2008.vcproj deleted file mode 100644 index 0c42dc72a1..0000000000 --- a/VisualC/tests/testgl2/testgl2_VS2008.vcproj +++ /dev/null @@ -1,359 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/VisualC/tests/testgles2/testgles2_VS2008.vcproj b/VisualC/tests/testgles2/testgles2_VS2008.vcproj deleted file mode 100644 index efe5355b86..0000000000 --- a/VisualC/tests/testgles2/testgles2_VS2008.vcproj +++ /dev/null @@ -1,352 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/VisualC/tests/testjoystick/testjoystick_VS2008.vcproj b/VisualC/tests/testjoystick/testjoystick_VS2008.vcproj deleted file mode 100644 index eb1a19fa6b..0000000000 --- a/VisualC/tests/testjoystick/testjoystick_VS2008.vcproj +++ /dev/null @@ -1,348 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/VisualC/tests/testoverlay2/testoverlay2_VS2008.vcproj b/VisualC/tests/testoverlay2/testoverlay2_VS2008.vcproj deleted file mode 100644 index 578a7c34a2..0000000000 --- a/VisualC/tests/testoverlay2/testoverlay2_VS2008.vcproj +++ /dev/null @@ -1,392 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/VisualC/tests/testplatform/testplatform_VS2008.vcproj b/VisualC/tests/testplatform/testplatform_VS2008.vcproj deleted file mode 100644 index 014faeeaa0..0000000000 --- a/VisualC/tests/testplatform/testplatform_VS2008.vcproj +++ /dev/null @@ -1,364 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/VisualC/tests/testpower/testpower_VS2008.vcproj b/VisualC/tests/testpower/testpower_VS2008.vcproj deleted file mode 100644 index e140e6b947..0000000000 --- a/VisualC/tests/testpower/testpower_VS2008.vcproj +++ /dev/null @@ -1,348 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/VisualC/tests/testrendertarget/testrendertarget_VS2008.vcproj b/VisualC/tests/testrendertarget/testrendertarget_VS2008.vcproj deleted file mode 100644 index d13432ac22..0000000000 --- a/VisualC/tests/testrendertarget/testrendertarget_VS2008.vcproj +++ /dev/null @@ -1,443 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/VisualC/tests/testrumble/testrumble_VS2008.vcproj b/VisualC/tests/testrumble/testrumble_VS2008.vcproj deleted file mode 100644 index ea4a858365..0000000000 --- a/VisualC/tests/testrumble/testrumble_VS2008.vcproj +++ /dev/null @@ -1,348 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/VisualC/tests/testscale/testscale_VS2008.vcproj b/VisualC/tests/testscale/testscale_VS2008.vcproj deleted file mode 100644 index 5a15fccf8d..0000000000 --- a/VisualC/tests/testscale/testscale_VS2008.vcproj +++ /dev/null @@ -1,443 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/VisualC/tests/testshape/testshape_VS2008.vcproj b/VisualC/tests/testshape/testshape_VS2008.vcproj deleted file mode 100644 index 73db789315..0000000000 --- a/VisualC/tests/testshape/testshape_VS2008.vcproj +++ /dev/null @@ -1,348 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/VisualC/tests/testsprite2/testsprite2_VS2008.vcproj b/VisualC/tests/testsprite2/testsprite2_VS2008.vcproj deleted file mode 100644 index 7236ecc4f8..0000000000 --- a/VisualC/tests/testsprite2/testsprite2_VS2008.vcproj +++ /dev/null @@ -1,399 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/VisualC/tests/testvulkan/testvulkan_VS2008.vcproj b/VisualC/tests/testvulkan/testvulkan_VS2008.vcproj deleted file mode 100644 index e413b52e9b..0000000000 --- a/VisualC/tests/testvulkan/testvulkan_VS2008.vcproj +++ /dev/null @@ -1,355 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From 10d7c4729e8d9ec7920e98b78038be58068c5557 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 22 Sep 2017 17:29:32 -0700 Subject: [PATCH 14/95] Added an example for SDL_SetWindowHitTest() when you create a borderless resizable window. --- src/test/SDL_test_common.c | 74 ++++++++++++++++++++++++++++++++------ 1 file changed, 63 insertions(+), 11 deletions(-) diff --git a/src/test/SDL_test_common.c b/src/test/SDL_test_common.c index 5bade2a206..b536e3808d 100644 --- a/src/test/SDL_test_common.c +++ b/src/test/SDL_test_common.c @@ -661,6 +661,52 @@ SDLTest_LoadIcon(const char *file) return (icon); } +static SDL_HitTestResult +SDLTest_ExampleHitTestCallback(SDL_Window *win, const SDL_Point *area, void *data) +{ + int w, h; + const int RESIZE_BORDER = 8; + const int DRAGGABLE_TITLE = 32; + + /*SDL_Log("Hit test point %d,%d\n", area->x, area->y);*/ + + SDL_GetWindowSize(win, &w, &h); + + if (area->x < RESIZE_BORDER) { + if (area->y < RESIZE_BORDER) { + SDL_Log("SDL_HITTEST_RESIZE_TOPLEFT\n"); + return SDL_HITTEST_RESIZE_TOPLEFT; + } else if (area->y >= (h-RESIZE_BORDER)) { + SDL_Log("SDL_HITTEST_RESIZE_BOTTOMLEFT\n"); + return SDL_HITTEST_RESIZE_BOTTOMLEFT; + } else { + SDL_Log("SDL_HITTEST_RESIZE_LEFT\n"); + return SDL_HITTEST_RESIZE_LEFT; + } + } else if (area->x >= (w-RESIZE_BORDER)) { + if (area->y < RESIZE_BORDER) { + SDL_Log("SDL_HITTEST_RESIZE_TOPRIGHT\n"); + return SDL_HITTEST_RESIZE_TOPRIGHT; + } else if (area->y >= (h-RESIZE_BORDER)) { + SDL_Log("SDL_HITTEST_RESIZE_BOTTOMRIGHT\n"); + return SDL_HITTEST_RESIZE_BOTTOMRIGHT; + } else { + SDL_Log("SDL_HITTEST_RESIZE_RIGHT\n"); + return SDL_HITTEST_RESIZE_RIGHT; + } + } else if (area->y >= (h-RESIZE_BORDER)) { + SDL_Log("SDL_HITTEST_RESIZE_BOTTOM\n"); + return SDL_HITTEST_RESIZE_BOTTOM; + } else if (area->y < RESIZE_BORDER) { + SDL_Log("SDL_HITTEST_RESIZE_TOP\n"); + return SDL_HITTEST_RESIZE_TOP; + } else if (area->y < DRAGGABLE_TITLE) { + SDL_Log("SDL_HITTEST_DRAGGABLE\n"); + return SDL_HITTEST_DRAGGABLE; + } + return SDL_HITTEST_NORMAL; +} + SDL_bool SDLTest_CommonInit(SDLTest_CommonState * state) { @@ -734,8 +780,8 @@ SDLTest_CommonInit(SDLTest_CommonState * state) int bpp; Uint32 Rmask, Gmask, Bmask, Amask; #if SDL_VIDEO_DRIVER_WINDOWS - int adapterIndex = 0; - int outputIndex = 0; + int adapterIndex = 0; + int outputIndex = 0; #endif n = SDL_GetNumVideoDisplays(); SDL_Log("Number of displays: %d\n", n); @@ -778,7 +824,7 @@ SDLTest_CommonInit(SDLTest_CommonState * state) SDL_GetDisplayMode(i, j, &mode); SDL_PixelFormatEnumToMasks(mode.format, &bpp, &Rmask, &Gmask, &Bmask, &Amask); - SDL_Log(" Mode %d: %dx%d@%dHz, %d bits-per-pixel (%s)\n", + SDL_Log(" Mode %d: %dx%d@%dHz, %d bits-per-pixel (%s)\n", j, mode.w, mode.h, mode.refresh_rate, bpp, SDL_GetPixelFormatName(mode.format)); if (Rmask || Gmask || Bmask) { @@ -789,20 +835,20 @@ SDLTest_CommonInit(SDLTest_CommonState * state) SDL_Log(" Blue Mask = 0x%.8x\n", Bmask); if (Amask) - SDL_Log(" Alpha Mask = 0x%.8x\n", + SDL_Log(" Alpha Mask = 0x%.8x\n", Amask); } } } #if SDL_VIDEO_DRIVER_WINDOWS - /* Print the D3D9 adapter index */ - adapterIndex = SDL_Direct3D9GetAdapterIndex( i ); - SDL_Log("D3D9 Adapter Index: %d", adapterIndex); + /* Print the D3D9 adapter index */ + adapterIndex = SDL_Direct3D9GetAdapterIndex( i ); + SDL_Log("D3D9 Adapter Index: %d", adapterIndex); - /* Print the DXGI adapter and output indices */ - SDL_DXGIGetOutputInfo(i, &adapterIndex, &outputIndex); - SDL_Log("DXGI Adapter Index: %d Output Index: %d", adapterIndex, outputIndex); + /* Print the DXGI adapter and output indices */ + SDL_DXGIGetOutputInfo(i, &adapterIndex, &outputIndex); + SDL_Log("DXGI Adapter Index: %d Output Index: %d", adapterIndex, outputIndex); #endif } } @@ -892,6 +938,12 @@ SDLTest_CommonInit(SDLTest_CommonState * state) return SDL_FALSE; } + /* Add resize/drag areas for windows that are borderless and resizable */ + if ((state->window_flags & SDL_WINDOW_RESIZABLE|SDL_WINDOW_BORDERLESS) == + (SDL_WINDOW_RESIZABLE|SDL_WINDOW_BORDERLESS)) { + SDL_SetWindowHitTest(state->windows[i], SDLTest_ExampleHitTestCallback, NULL); + } + if (state->window_icon) { SDL_Surface *icon = SDLTest_LoadIcon(state->window_icon); if (icon) { @@ -918,7 +970,7 @@ SDLTest_CommonInit(SDLTest_CommonState * state) } } if (m == -1) { - SDL_Log("Couldn't find render driver named %s", + SDL_Log("Couldn't find render driver named %s", state->renderdriver); return SDL_FALSE; } From eb37c8107d969cdd80fb9f2a027056573ee6f9e0 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 22 Sep 2017 17:32:05 -0700 Subject: [PATCH 15/95] Fixed spacing --- src/video/windows/SDL_windowswindow.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/video/windows/SDL_windowswindow.c b/src/video/windows/SDL_windowswindow.c index 50fdec9a19..336e1e1c88 100644 --- a/src/video/windows/SDL_windowswindow.c +++ b/src/video/windows/SDL_windowswindow.c @@ -97,8 +97,8 @@ WIN_AdjustWindowRectWithStyle(SDL_Window *window, DWORD style, BOOL menu, int *x // borderless windows will have WM_NCCALCSIZE return 0 for the non-client area. When this happens, it looks like windows will send a resize message // expanding the window client area to the previous window + chrome size, so shouldn't need to adjust the window size for the set styles. - if ( !(window->flags & SDL_WINDOW_BORDERLESS) ) - AdjustWindowRectEx( &rect, style, menu, 0 ); + if (!(window->flags & SDL_WINDOW_BORDERLESS)) + AdjustWindowRectEx(&rect, style, menu, 0); *x = (use_current ? window->x : window->windowed.x) + rect.left; *y = (use_current ? window->y : window->windowed.y) + rect.top; @@ -316,7 +316,7 @@ WIN_CreateWindow(_THIS, SDL_Window * window) } // Inform Windows of the frame change so we can respond to WM_NCCALCSIZE - SetWindowPos( hwnd, NULL, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE ); + SetWindowPos(hwnd, NULL, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE); if (!(window->flags & SDL_WINDOW_OPENGL)) { return 0; From 6817412ce8d053ddf70634441a23983f162cf50b Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 22 Sep 2017 22:28:21 -0400 Subject: [PATCH 16/95] audio: Fixed compiler warning on Visual Studio. --- src/audio/SDL_audiocvt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/audio/SDL_audiocvt.c b/src/audio/SDL_audiocvt.c index 4b24ccdb39..f2d2464817 100644 --- a/src/audio/SDL_audiocvt.c +++ b/src/audio/SDL_audiocvt.c @@ -497,7 +497,7 @@ SDL_ResampleAudio(const int chans, const int inrate, const int outrate, const float interpolation1 = 1.0f - (innexttime - outtime) / (innexttime - intime); const int filterindex1 = (int) (interpolation1 * RESAMPLER_SAMPLES_PER_ZERO_CROSSING); const float interpolation2 = 1.0f - interpolation1; - const int filterindex2 = interpolation2 * RESAMPLER_SAMPLES_PER_ZERO_CROSSING; + const int filterindex2 = (int) (interpolation2 * RESAMPLER_SAMPLES_PER_ZERO_CROSSING); for (chan = 0; chan < chans; chan++) { float outsample = 0.0f; From e7d683c6d82b05e171ce0e03dc0f2e243daa0c03 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sat, 23 Sep 2017 12:37:09 -0700 Subject: [PATCH 17/95] Fixed bug 3843 - Android missing some code in SDLHapticHandler Sylvain Some check for android SDK version are missing from https://hg.libsdl.org/SDL/rev/04dd43a2c83a here's a patch --- .../org/libsdl/app/SDLControllerManager.java | 66 +++++++++++-------- 1 file changed, 37 insertions(+), 29 deletions(-) diff --git a/android-project/src/org/libsdl/app/SDLControllerManager.java b/android-project/src/org/libsdl/app/SDLControllerManager.java index c050764dab..ef946acd59 100644 --- a/android-project/src/org/libsdl/app/SDLControllerManager.java +++ b/android-project/src/org/libsdl/app/SDLControllerManager.java @@ -300,7 +300,7 @@ public void run(int device_id, int length) { public void pollHapticDevices() { final int deviceId_VIBRATOR_SERVICE = 999999; - boolean hasVibrator = false; + boolean hasVibratorService = false; int[] deviceIds = InputDevice.getDeviceIds(); // It helps processing the device ids in reverse order @@ -308,37 +308,45 @@ public void pollHapticDevices() { // so the first controller seen by SDL matches what the receiver // considers to be the first controller - for(int i=deviceIds.length-1; i>-1; i--) { - SDLHaptic haptic = getHaptic(deviceIds[i]); - if (haptic == null) { - InputDevice device = InputDevice.getDevice(deviceIds[i]); - Vibrator vib = device.getVibrator(); - if (vib.hasVibrator()) { - haptic = new SDLHaptic(); - haptic.device_id = deviceIds[i]; - haptic.name = device.getName(); - haptic.vib = vib; - mHaptics.add(haptic); - SDLControllerManager.nativeAddHaptic(haptic.device_id, haptic.name); + if (Build.VERSION.SDK_INT >= 16) + { + for (int i = deviceIds.length - 1; i > -1; i--) { + SDLHaptic haptic = getHaptic(deviceIds[i]); + if (haptic == null) { + InputDevice device = InputDevice.getDevice(deviceIds[i]); + Vibrator vib = device.getVibrator(); + if (vib.hasVibrator()) { + haptic = new SDLHaptic(); + haptic.device_id = deviceIds[i]; + haptic.name = device.getName(); + haptic.vib = vib; + mHaptics.add(haptic); + SDLControllerManager.nativeAddHaptic(haptic.device_id, haptic.name); + } } } } /* Check VIBRATOR_SERVICE */ - { - Vibrator vib = (Vibrator) SDL.getContext().getSystemService(Context.VIBRATOR_SERVICE); - if (vib != null && vib.hasVibrator()) { - hasVibrator = true; - SDLHaptic haptic = getHaptic(deviceId_VIBRATOR_SERVICE); - if (haptic == null) { - haptic = new SDLHaptic(); - haptic.device_id = deviceId_VIBRATOR_SERVICE; - haptic.name = "VIBRATOR_SERVICE"; - haptic.vib = vib; - mHaptics.add(haptic); - SDLControllerManager.nativeAddHaptic(haptic.device_id, haptic.name); - } - } + Vibrator vib = (Vibrator) SDL.getContext().getSystemService(Context.VIBRATOR_SERVICE); + if (vib != null) { + if (Build.VERSION.SDK_INT >= 11) { + hasVibratorService = vib.hasVibrator(); + } else { + hasVibratorService = true; + } + + if (hasVibratorService) { + SDLHaptic haptic = getHaptic(deviceId_VIBRATOR_SERVICE); + if (haptic == null) { + haptic = new SDLHaptic(); + haptic.device_id = deviceId_VIBRATOR_SERVICE; + haptic.name = "VIBRATOR_SERVICE"; + haptic.vib = vib; + mHaptics.add(haptic); + SDLControllerManager.nativeAddHaptic(haptic.device_id, haptic.name); + } + } } /* Check removed devices */ @@ -350,8 +358,8 @@ public void pollHapticDevices() { if (device_id == deviceIds[j]) break; } - if (device_id == deviceId_VIBRATOR_SERVICE && hasVibrator) { - // don't remove the vibrator if it is still present + if (device_id == deviceId_VIBRATOR_SERVICE && hasVibratorService) { + // don't remove the vibrator if it is still present } else if (j == deviceIds.length) { removedDevices.add(device_id); } From b618eb6e7dc4d6d9ab94ed9890a84da3fb09a15d Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sat, 23 Sep 2017 12:38:47 -0700 Subject: [PATCH 18/95] Fixed bug 3842 - fix SDL_thread.h for emx Ozkan Sezer EMX declares _beginthread() / _endthread() in stdlib.h, not process.h. The attached patch updates the OS/2 case of SDL_thread.h for it. (It also tidies the unreadable whitespace in win32 case.) --- include/SDL_thread.h | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/include/SDL_thread.h b/include/SDL_thread.h index cf1ce492fa..d0f6575cd5 100644 --- a/include/SDL_thread.h +++ b/include/SDL_thread.h @@ -90,14 +90,11 @@ typedef int (SDLCALL * SDL_ThreadFunction) (void *data); * library! */ #define SDL_PASSED_BEGINTHREAD_ENDTHREAD -#include /* This has _beginthread() and _endthread() defined! */ - -typedef uintptr_t(__cdecl * pfnSDL_CurrentBeginThread) (void *, unsigned, - unsigned (__stdcall * - func) (void - *), - void *arg, unsigned, - unsigned *threadID); +#include /* _beginthreadex() and _endthreadex() */ + +typedef uintptr_t(__cdecl * pfnSDL_CurrentBeginThread) + (void *, unsigned, unsigned (__stdcall *func)(void *), + void * /*arg*/, unsigned, unsigned * /* threadID */); typedef void (__cdecl * pfnSDL_CurrentEndThread) (unsigned code); /** @@ -124,7 +121,11 @@ SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data, * into a dll with Watcom's runtime statically linked. */ #define SDL_PASSED_BEGINTHREAD_ENDTHREAD +#ifndef __EMX__ #include +#else +#include +#endif typedef int (*pfnSDL_CurrentBeginThread)(void (*func)(void *), void *, unsigned, void * /*arg*/); typedef void (*pfnSDL_CurrentEndThread)(void); extern DECLSPEC SDL_Thread *SDLCALL From 7daad0d2d784195aabbab31f8f0d3ff01d0dcfd7 Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Mon, 25 Sep 2017 20:49:31 -0300 Subject: [PATCH 19/95] Mac: Fix the menu bar not always working for non-.app-bundled apps. Fixes bug #3051. --- src/video/cocoa/SDL_cocoaevents.m | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/video/cocoa/SDL_cocoaevents.m b/src/video/cocoa/SDL_cocoaevents.m index e428e4374d..98bdf87546 100644 --- a/src/video/cocoa/SDL_cocoaevents.m +++ b/src/video/cocoa/SDL_cocoaevents.m @@ -216,6 +216,18 @@ - (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filenam { return (BOOL)SDL_SendDropFile(NULL, [filename UTF8String]) && SDL_SendDropComplete(NULL); } + +- (void)applicationDidFinishLaunching:(NSNotification *)notification +{ + /* The menu bar of SDL apps which don't have the typical .app bundle + * structure fails to work the first time a window is created (until it's + * de-focused and re-focused), if this call is in Cocoa_RegisterApp instead + * of here. https://bugzilla.libsdl.org/show_bug.cgi?id=3051 + */ + if (!SDL_GetHintBoolean(SDL_HINT_MAC_BACKGROUND_APP, SDL_FALSE)) { + [NSApp activateIgnoringOtherApps:YES]; + } +} @end static SDLAppDelegate *appDelegate = nil; @@ -361,7 +373,6 @@ - (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filenam if (!SDL_GetHintBoolean(SDL_HINT_MAC_BACKGROUND_APP, SDL_FALSE)) { [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; - [NSApp activateIgnoringOtherApps:YES]; } if ([NSApp mainMenu] == nil) { From 12ab8eb7bc1981a5954d6275e37912a585bed92c Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 26 Sep 2017 15:07:35 -0700 Subject: [PATCH 20/95] Fixed bug 3847 - Hit Test x coordinate wrong on secondary monitor Robert Turner SDL_windowsevents.c contains code to retrieve the x and y coordinate for a requested hit test. It does this as follows: POINT winpoint = { (int) LOWORD(lParam), (int) HIWORD(lParam) }; LOWORD(lParam) does not correctly mask off high bits that are set if the point is on a second (or third, etc.) monitor. This effectively offsets the x-coordinate by a large value. MSDN documentation suggests that LOWORD() and HIWORD() are the wrong macros for the task, instead suggesting we should be doing something like the following: POINT winpoint = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; Testing this change on my Windows 10 machine with 2 monitors gives the correct results. --- src/video/windows/SDL_windowsevents.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/windows/SDL_windowsevents.c b/src/video/windows/SDL_windowsevents.c index 015ae88e2c..b73e9df8bd 100644 --- a/src/video/windows/SDL_windowsevents.c +++ b/src/video/windows/SDL_windowsevents.c @@ -961,7 +961,7 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { SDL_Window *window = data->window; if (window->hit_test) { - POINT winpoint = { (int) LOWORD(lParam), (int) HIWORD(lParam) }; + POINT winpoint = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; if (ScreenToClient(hwnd, &winpoint)) { const SDL_Point point = { (int) winpoint.x, (int) winpoint.y }; const SDL_HitTestResult rc = window->hit_test(window, &point, window->hit_test_data); From 0983eef11b55bbf3cb012a8d623d32099f483852 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 26 Sep 2017 16:27:24 -0700 Subject: [PATCH 21/95] Fixed bug 3850 - incorrect numbering in docs/README-ios.md Michal the numbering of the bulletpoints in: docs/README-ios.md has been mangled with: changeset 11365 a9bd2625fa01 fix: 12 2. Open SDL.xcodeproj (located in Xcode-iOS/SDL) in Xcode. 13 4. Select your desired target, and hit build. remove: 28 1. Follow step 1 above. adapt: 29 2. cd (PATH WHERE THE SDL CODE IS)/build-scripts 30 3. ./iosbuild.sh --- docs/README-ios.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/docs/README-ios.md b/docs/README-ios.md index 18c4bc0669..bf34fe482f 100644 --- a/docs/README-ios.md +++ b/docs/README-ios.md @@ -9,8 +9,8 @@ Requirements: Mac OS X 10.8 or later and the iOS 7+ SDK. Instructions: -2. Open SDL.xcodeproj (located in Xcode-iOS/SDL) in Xcode. -4. Select your desired target, and hit build. +1. Open SDL.xcodeproj (located in Xcode-iOS/SDL) in Xcode. +2. Select your desired target, and hit build. There are three build targets: - libSDL.a: @@ -25,9 +25,8 @@ There are three build targets: Build SDL for iOS from the command line ============================================================================== -1. Follow step 1 above. -2. cd (PATH WHERE THE SDL CODE IS)/build-scripts -3. ./iosbuild.sh +1. cd (PATH WHERE THE SDL CODE IS)/build-scripts +2. ./iosbuild.sh If everything goes fine, you should see a build/ios directory, inside there's two directories "lib" and "include". From a78e8e589bd75168e3cd32344cea33e5cef67084 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 29 Sep 2017 07:44:30 -0700 Subject: [PATCH 22/95] Fixed bug 3852 - SDL_FreeSurface deallocates surface->map even if the surface is not yet freed Evgeny Kapun Commit 52dcef74bdc5 [1], which was a fix for bug #3790, introduced a new bug: now, calling SDL_FreeSurface(surface) deallocates surface->map even if there are other references to the surface. This is bad, because some functions (such as SDL_ConvertSurface) assume that surface->map is not NULL. --- src/video/SDL_surface.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/video/SDL_surface.c b/src/video/SDL_surface.c index 600056fe93..75b699c3a0 100644 --- a/src/video/SDL_surface.c +++ b/src/video/SDL_surface.c @@ -1198,10 +1198,8 @@ SDL_FreeSurface(SDL_Surface * surface) if (surface->flags & SDL_DONTFREE) { return; } - if (surface->map != NULL) { - SDL_FreeBlitMap(surface->map); - surface->map = NULL; - } + SDL_InvalidateMap(surface->map); + if (--surface->refcount > 0) { return; } From cd0c2ee64492a8f305f84817971fd5e5f7feb2b9 Mon Sep 17 00:00:00 2001 From: Brandon Schaefer Date: Fri, 29 Sep 2017 10:07:37 -0700 Subject: [PATCH 23/95] wayland: Fix bug 3814 -Wmissing-field-initializers --- configure | 15 +- configure.in | 1 + include/SDL_config.h | 382 ++++++++++++++++++++++++-- include/SDL_revision.h | 4 +- src/core/linux/SDL_udev.c | 1 + src/loadso/dlopen/SDL_sysloadso.c | 1 + src/video/SDL_egl.c | 2 + src/video/wayland/SDL_waylandevents.c | 10 +- src/video/wayland/SDL_waylandvideo.c | 3 +- test/configure | 14 +- test/testgl2.c | 2 + 11 files changed, 408 insertions(+), 27 deletions(-) diff --git a/configure b/configure index 1cb707e2b7..0b69f623e4 100755 --- a/configure +++ b/configure @@ -745,6 +745,7 @@ infodir docdir oldincludedir includedir +runstatedir localstatedir sharedstatedir sysconfdir @@ -922,6 +923,7 @@ datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' +runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE}' @@ -1174,6 +1176,15 @@ do | -silent | --silent | --silen | --sile | --sil) silent=yes ;; + -runstatedir | --runstatedir | --runstatedi | --runstated \ + | --runstate | --runstat | --runsta | --runst | --runs \ + | --run | --ru | --r) + ac_prev=runstatedir ;; + -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ + | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ + | --run=* | --ru=* | --r=*) + runstatedir=$ac_optarg ;; + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ @@ -1311,7 +1322,7 @@ fi for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir + libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. @@ -1464,6 +1475,7 @@ Fine tuning of the installation directories: --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] @@ -19104,6 +19116,7 @@ $as_echo "$need_gcc_Wno_multichar" >&6; } CheckWayland() { + EXTRA_CFLAGS="$EXTRA_CFLAGS -Wall -Wmissing-field-initializers" # Check whether --enable-video-wayland was given. if test "${enable_video_wayland+set}" = set; then : enableval=$enable_video_wayland; diff --git a/configure.in b/configure.in index 33572d7a15..6aa57d3dbb 100644 --- a/configure.in +++ b/configure.in @@ -1366,6 +1366,7 @@ CheckWarnAll() dnl Check for Wayland CheckWayland() { + EXTRA_CFLAGS="$EXTRA_CFLAGS -Wall -Wmissing-field-initializers" AC_ARG_ENABLE(video-wayland, AC_HELP_STRING([--enable-video-wayland], [use Wayland video driver [[default=yes]]]), ,enable_video_wayland=yes) diff --git a/include/SDL_config.h b/include/SDL_config.h index 41f5baabe5..54d82244d2 100644 --- a/include/SDL_config.h +++ b/include/SDL_config.h @@ -1,3 +1,4 @@ +/* include/SDL_config.h. Generated from SDL_config.h.in by configure. */ /* Simple DirectMedia Layer Copyright (C) 1997-2017 Sam Lantinga @@ -22,32 +23,371 @@ #ifndef SDL_config_h_ #define SDL_config_h_ -#include "SDL_platform.h" - /** - * \file SDL_config.h + * \file SDL_config.h.in + * + * This is a set of defines to configure the SDL features */ -/* Add any platform that doesn't build using the configure system. */ -#if defined(__WIN32__) -#include "SDL_config_windows.h" -#elif defined(__WINRT__) -#include "SDL_config_winrt.h" -#elif defined(__MACOSX__) -#include "SDL_config_macosx.h" -#elif defined(__IPHONEOS__) -#include "SDL_config_iphoneos.h" -#elif defined(__ANDROID__) -#include "SDL_config_android.h" -#elif defined(__PSP__) -#include "SDL_config_psp.h" +/* General platform specific identifiers */ +#include "SDL_platform.h" + +/* Make sure that this isn't included by Visual C++ */ +#ifdef _MSC_VER +#error You should run hg revert SDL_config.h +#endif + +/* C language features */ +/* #undef const */ +/* #undef inline */ +/* #undef volatile */ + +/* C datatypes */ +#ifdef __LP64__ +#define SIZEOF_VOIDP 8 #else -/* This is a minimal configuration just to get SDL running on new platforms */ -#include "SDL_config_minimal.h" -#endif /* platform config */ +#define SIZEOF_VOIDP 4 +#endif +#define HAVE_GCC_ATOMICS 1 +/* #undef HAVE_GCC_SYNC_LOCK_TEST_AND_SET */ -#ifdef USING_GENERATED_CONFIG_H -#error Wrong SDL_config.h, check your include path? +/* Comment this if you want to build without any C library requirements */ +#define HAVE_LIBC 1 +#if HAVE_LIBC + +/* Useful headers */ +#define STDC_HEADERS 1 +#define HAVE_ALLOCA_H 1 +#define HAVE_CTYPE_H 1 +#define HAVE_FLOAT_H 1 +#define HAVE_ICONV_H 1 +#define HAVE_INTTYPES_H 1 +#define HAVE_LIMITS_H 1 +#define HAVE_MALLOC_H 1 +#define HAVE_MATH_H 1 +#define HAVE_MEMORY_H 1 +#define HAVE_SIGNAL_H 1 +#define HAVE_STDARG_H 1 +#define HAVE_STDINT_H 1 +#define HAVE_STDIO_H 1 +#define HAVE_STDLIB_H 1 +#define HAVE_STRINGS_H 1 +#define HAVE_STRING_H 1 +#define HAVE_SYS_TYPES_H 1 +#define HAVE_WCHAR_H 1 +/* #undef HAVE_PTHREAD_NP_H */ + +/* C library functions */ +#define HAVE_MALLOC 1 +#define HAVE_CALLOC 1 +#define HAVE_REALLOC 1 +#define HAVE_FREE 1 +#define HAVE_ALLOCA 1 +#ifndef __WIN32__ /* Don't use C runtime versions of these on Windows */ +#define HAVE_GETENV 1 +#define HAVE_SETENV 1 +#define HAVE_PUTENV 1 +#define HAVE_UNSETENV 1 #endif +#define HAVE_QSORT 1 +#define HAVE_ABS 1 +#define HAVE_BCOPY 1 +#define HAVE_MEMSET 1 +#define HAVE_MEMCPY 1 +#define HAVE_MEMMOVE 1 +#define HAVE_MEMCMP 1 +#define HAVE_WCSLEN 1 +/* #undef HAVE_WCSLCPY */ +/* #undef HAVE_WCSLCAT */ +#define HAVE_WCSCMP 1 +#define HAVE_STRLEN 1 +/* #undef HAVE_STRLCPY */ +/* #undef HAVE_STRLCAT */ +#define HAVE_STRDUP 1 +/* #undef HAVE__STRREV */ +/* #undef HAVE__STRUPR */ +/* #undef HAVE__STRLWR */ +/* #undef HAVE_INDEX */ +/* #undef HAVE_RINDEX */ +#define HAVE_STRCHR 1 +#define HAVE_STRRCHR 1 +#define HAVE_STRSTR 1 +/* #undef HAVE_ITOA */ +/* #undef HAVE__LTOA */ +/* #undef HAVE__UITOA */ +/* #undef HAVE__ULTOA */ +#define HAVE_STRTOL 1 +#define HAVE_STRTOUL 1 +/* #undef HAVE__I64TOA */ +/* #undef HAVE__UI64TOA */ +#define HAVE_STRTOLL 1 +#define HAVE_STRTOULL 1 +#define HAVE_STRTOD 1 +#define HAVE_ATOI 1 +#define HAVE_ATOF 1 +#define HAVE_STRCMP 1 +#define HAVE_STRNCMP 1 +/* #undef HAVE__STRICMP */ +#define HAVE_STRCASECMP 1 +/* #undef HAVE__STRNICMP */ +#define HAVE_STRNCASECMP 1 +/* #undef HAVE_SSCANF */ +#define HAVE_VSSCANF 1 +/* #undef HAVE_SNPRINTF */ +#define HAVE_VSNPRINTF 1 +#define HAVE_M_PI /**/ +#define HAVE_ATAN 1 +#define HAVE_ATAN2 1 +#define HAVE_ACOS 1 +#define HAVE_ASIN 1 +#define HAVE_CEIL 1 +#define HAVE_COPYSIGN 1 +#define HAVE_COS 1 +#define HAVE_COSF 1 +#define HAVE_FABS 1 +#define HAVE_FLOOR 1 +#define HAVE_LOG 1 +#define HAVE_POW 1 +#define HAVE_SCALBN 1 +#define HAVE_SIN 1 +#define HAVE_SINF 1 +#define HAVE_SQRT 1 +#define HAVE_SQRTF 1 +#define HAVE_TAN 1 +#define HAVE_TANF 1 +#define HAVE_FOPEN64 1 +#define HAVE_FSEEKO 1 +#define HAVE_FSEEKO64 1 +#define HAVE_SIGACTION 1 +#define HAVE_SA_SIGACTION 1 +#define HAVE_SETJMP 1 +#define HAVE_NANOSLEEP 1 +#define HAVE_SYSCONF 1 +/* #undef HAVE_SYSCTLBYNAME */ +#define HAVE_CLOCK_GETTIME 1 +/* #undef HAVE_GETPAGESIZE */ +#define HAVE_MPROTECT 1 +#define HAVE_ICONV 1 +#define HAVE_PTHREAD_SETNAME_NP 1 +/* #undef HAVE_PTHREAD_SET_NAME_NP */ +#define HAVE_SEM_TIMEDWAIT 1 +#define HAVE_GETAUXVAL 1 +#define HAVE_POLL 1 + +#else +#define HAVE_STDARG_H 1 +#define HAVE_STDDEF_H 1 +#define HAVE_STDINT_H 1 +#endif /* HAVE_LIBC */ + +/* #undef HAVE_ALTIVEC_H */ +#define HAVE_LIBUDEV_H 1 +#define HAVE_DBUS_DBUS_H 1 +#define HAVE_IBUS_IBUS_H 1 +/* #undef HAVE_FCITX_FRONTEND_H */ +#define HAVE_LIBSAMPLERATE_H 1 + +/* #undef HAVE_DDRAW_H */ +/* #undef HAVE_DINPUT_H */ +/* #undef HAVE_DSOUND_H */ +/* #undef HAVE_DXGI_H */ +/* #undef HAVE_XINPUT_H */ +/* #undef HAVE_XINPUT_GAMEPAD_EX */ +/* #undef HAVE_XINPUT_STATE_EX */ + +/* SDL internal assertion support */ +/* #undef SDL_DEFAULT_ASSERT_LEVEL */ + +/* Allow disabling of core subsystems */ +/* #undef SDL_ATOMIC_DISABLED */ +/* #undef SDL_AUDIO_DISABLED */ +/* #undef SDL_CPUINFO_DISABLED */ +/* #undef SDL_EVENTS_DISABLED */ +/* #undef SDL_FILE_DISABLED */ +/* #undef SDL_JOYSTICK_DISABLED */ +/* #undef SDL_HAPTIC_DISABLED */ +/* #undef SDL_LOADSO_DISABLED */ +/* #undef SDL_RENDER_DISABLED */ +/* #undef SDL_THREADS_DISABLED */ +/* #undef SDL_TIMERS_DISABLED */ +/* #undef SDL_VIDEO_DISABLED */ +/* #undef SDL_POWER_DISABLED */ +/* #undef SDL_FILESYSTEM_DISABLED */ + +/* Enable various audio drivers */ +#define SDL_AUDIO_DRIVER_ALSA 1 +#define SDL_AUDIO_DRIVER_ALSA_DYNAMIC "libasound.so.2" +/* #undef SDL_AUDIO_DRIVER_ANDROID */ +/* #undef SDL_AUDIO_DRIVER_ARTS */ +/* #undef SDL_AUDIO_DRIVER_ARTS_DYNAMIC */ +/* #undef SDL_AUDIO_DRIVER_COREAUDIO */ +#define SDL_AUDIO_DRIVER_DISK 1 +/* #undef SDL_AUDIO_DRIVER_DSOUND */ +#define SDL_AUDIO_DRIVER_DUMMY 1 +/* #undef SDL_AUDIO_DRIVER_EMSCRIPTEN */ +/* #undef SDL_AUDIO_DRIVER_ESD */ +/* #undef SDL_AUDIO_DRIVER_ESD_DYNAMIC */ +/* #undef SDL_AUDIO_DRIVER_FUSIONSOUND */ +/* #undef SDL_AUDIO_DRIVER_FUSIONSOUND_DYNAMIC */ +/* #undef SDL_AUDIO_DRIVER_HAIKU */ +#define SDL_AUDIO_DRIVER_JACK 1 +#define SDL_AUDIO_DRIVER_JACK_DYNAMIC "libjack.so.0" +/* #undef SDL_AUDIO_DRIVER_NACL */ +/* #undef SDL_AUDIO_DRIVER_NAS */ +/* #undef SDL_AUDIO_DRIVER_NAS_DYNAMIC */ +/* #undef SDL_AUDIO_DRIVER_NETBSD */ +#define SDL_AUDIO_DRIVER_OSS 1 +/* #undef SDL_AUDIO_DRIVER_OSS_SOUNDCARD_H */ +/* #undef SDL_AUDIO_DRIVER_PAUDIO */ +#define SDL_AUDIO_DRIVER_PULSEAUDIO 1 +#define SDL_AUDIO_DRIVER_PULSEAUDIO_DYNAMIC "libpulse-simple.so.0" +/* #undef SDL_AUDIO_DRIVER_QSA */ +#define SDL_AUDIO_DRIVER_SNDIO 1 +/* #undef SDL_AUDIO_DRIVER_SNDIO_DYNAMIC */ +/* #undef SDL_AUDIO_DRIVER_SUNAUDIO */ +/* #undef SDL_AUDIO_DRIVER_WASAPI */ +/* #undef SDL_AUDIO_DRIVER_WINMM */ +/* #undef SDL_AUDIO_DRIVER_XAUDIO2 */ + +/* Enable various input drivers */ +#define SDL_INPUT_LINUXEV 1 +#define SDL_INPUT_LINUXKD 1 +/* #undef SDL_INPUT_TSLIB */ +/* #undef SDL_JOYSTICK_HAIKU */ +/* #undef SDL_JOYSTICK_DINPUT */ +/* #undef SDL_JOYSTICK_XINPUT */ +/* #undef SDL_JOYSTICK_DUMMY */ +/* #undef SDL_JOYSTICK_IOKIT */ +#define SDL_JOYSTICK_LINUX 1 +/* #undef SDL_JOYSTICK_ANDROID */ +/* #undef SDL_JOYSTICK_WINMM */ +/* #undef SDL_JOYSTICK_USBHID */ +/* #undef SDL_JOYSTICK_USBHID_MACHINE_JOYSTICK_H */ +/* #undef SDL_JOYSTICK_EMSCRIPTEN */ +/* #undef SDL_HAPTIC_DUMMY */ +#define SDL_HAPTIC_LINUX 1 +/* #undef SDL_HAPTIC_IOKIT */ +/* #undef SDL_HAPTIC_DINPUT */ +/* #undef SDL_HAPTIC_XINPUT */ + +/* Enable various shared object loading systems */ +#define SDL_LOADSO_DLOPEN 1 +/* #undef SDL_LOADSO_DUMMY */ +/* #undef SDL_LOADSO_LDG */ +/* #undef SDL_LOADSO_WINDOWS */ + +/* Enable various threading systems */ +#define SDL_THREAD_PTHREAD 1 +#define SDL_THREAD_PTHREAD_RECURSIVE_MUTEX 1 +/* #undef SDL_THREAD_PTHREAD_RECURSIVE_MUTEX_NP */ +/* #undef SDL_THREAD_WINDOWS */ + +/* Enable various timer systems */ +/* #undef SDL_TIMER_HAIKU */ +/* #undef SDL_TIMER_DUMMY */ +#define SDL_TIMER_UNIX 1 +/* #undef SDL_TIMER_WINDOWS */ + +/* Enable various video drivers */ +/* #undef SDL_VIDEO_DRIVER_HAIKU */ +/* #undef SDL_VIDEO_DRIVER_COCOA */ +/* #undef SDL_VIDEO_DRIVER_DIRECTFB */ +/* #undef SDL_VIDEO_DRIVER_DIRECTFB_DYNAMIC */ +#define SDL_VIDEO_DRIVER_DUMMY 1 +/* #undef SDL_VIDEO_DRIVER_WINDOWS */ +#define SDL_VIDEO_DRIVER_WAYLAND 1 +#define SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH 1 +#define SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC "libwayland-client.so.0" +#define SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_EGL "libwayland-egl.so.1" +#define SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_CURSOR "libwayland-cursor.so.0" +#define SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_XKBCOMMON "libxkbcommon.so.0" +/* #undef SDL_VIDEO_DRIVER_MIR */ +/* #undef SDL_VIDEO_DRIVER_MIR_DYNAMIC */ +/* #undef SDL_VIDEO_DRIVER_MIR_DYNAMIC_XKBCOMMON */ +#define SDL_VIDEO_DRIVER_X11 1 +/* #undef SDL_VIDEO_DRIVER_RPI */ +/* #undef SDL_VIDEO_DRIVER_KMSDRM */ +/* #undef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC */ +/* #undef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC_GBM */ +/* #undef SDL_VIDEO_DRIVER_ANDROID */ +/* #undef SDL_VIDEO_DRIVER_EMSCRIPTEN */ +#define SDL_VIDEO_DRIVER_X11_DYNAMIC "libX11.so.6" +#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT "libXext.so.6" +#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XCURSOR "libXcursor.so.1" +#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XINERAMA "libXinerama.so.1" +#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT2 "libXi.so.6" +#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR "libXrandr.so.2" +#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS "libXss.so.1" +#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XVIDMODE "libXxf86vm.so.1" +#define SDL_VIDEO_DRIVER_X11_XCURSOR 1 +#define SDL_VIDEO_DRIVER_X11_XDBE 1 +#define SDL_VIDEO_DRIVER_X11_XINERAMA 1 +#define SDL_VIDEO_DRIVER_X11_XINPUT2 1 +#define SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH 1 +#define SDL_VIDEO_DRIVER_X11_XRANDR 1 +#define SDL_VIDEO_DRIVER_X11_XSCRNSAVER 1 +#define SDL_VIDEO_DRIVER_X11_XSHAPE 1 +#define SDL_VIDEO_DRIVER_X11_XVIDMODE 1 +#define SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS 1 +#define SDL_VIDEO_DRIVER_X11_CONST_PARAM_XEXTADDDISPLAY 1 +#define SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM 1 +/* #undef SDL_VIDEO_DRIVER_NACL */ +/* #undef SDL_VIDEO_DRIVER_VIVANTE */ +/* #undef SDL_VIDEO_DRIVER_VIVANTE_VDK */ +/* #undef SDL_VIDEO_DRIVER_QNX */ + +/* #undef SDL_VIDEO_RENDER_D3D */ +/* #undef SDL_VIDEO_RENDER_D3D11 */ +#define SDL_VIDEO_RENDER_OGL 1 +/* #undef SDL_VIDEO_RENDER_OGL_ES */ +#define SDL_VIDEO_RENDER_OGL_ES2 1 +/* #undef SDL_VIDEO_RENDER_DIRECTFB */ + +/* Enable OpenGL support */ +#define SDL_VIDEO_OPENGL 1 +/* #undef SDL_VIDEO_OPENGL_ES */ +#define SDL_VIDEO_OPENGL_ES2 1 +/* #undef SDL_VIDEO_OPENGL_BGL */ +/* #undef SDL_VIDEO_OPENGL_CGL */ +#define SDL_VIDEO_OPENGL_EGL 1 +#define SDL_VIDEO_OPENGL_GLX 1 +/* #undef SDL_VIDEO_OPENGL_WGL */ +/* #undef SDL_VIDEO_OPENGL_OSMESA */ +/* #undef SDL_VIDEO_OPENGL_OSMESA_DYNAMIC */ + +/* Enable Vulkan support */ +#define SDL_VIDEO_VULKAN 1 + +/* Enable system power support */ +#define SDL_POWER_LINUX 1 +/* #undef SDL_POWER_WINDOWS */ +/* #undef SDL_POWER_MACOSX */ +/* #undef SDL_POWER_HAIKU */ +/* #undef SDL_POWER_ANDROID */ +/* #undef SDL_POWER_EMSCRIPTEN */ +/* #undef SDL_POWER_HARDWIRED */ + +/* Enable system filesystem support */ +/* #undef SDL_FILESYSTEM_HAIKU */ +/* #undef SDL_FILESYSTEM_COCOA */ +/* #undef SDL_FILESYSTEM_DUMMY */ +#define SDL_FILESYSTEM_UNIX 1 +/* #undef SDL_FILESYSTEM_WINDOWS */ +/* #undef SDL_FILESYSTEM_NACL */ +/* #undef SDL_FILESYSTEM_ANDROID */ +/* #undef SDL_FILESYSTEM_EMSCRIPTEN */ + +/* Enable assembly routines */ +#define SDL_ASSEMBLY_ROUTINES 1 +/* #undef SDL_ALTIVEC_BLITTERS */ + +/* Enable ime support */ +#define SDL_USE_IME 1 + +/* Enable dynamic udev support */ +#define SDL_UDEV_DYNAMIC "libudev.so.1" + +/* Enable dynamic libsamplerate support */ +#define SDL_LIBSAMPLERATE_DYNAMIC "libsamplerate.so.0" #endif /* SDL_config_h_ */ diff --git a/include/SDL_revision.h b/include/SDL_revision.h index d70fd694ea..ecd1d57282 100644 --- a/include/SDL_revision.h +++ b/include/SDL_revision.h @@ -1,2 +1,2 @@ -#define SDL_REVISION "hg-0:aaaaaaaaaaah" -#define SDL_REVISION_NUMBER 0 +#define SDL_REVISION "hg-11511:833d4fbb3d76" +#define SDL_REVISION_NUMBER 11511 diff --git a/src/core/linux/SDL_udev.c b/src/core/linux/SDL_udev.c index 502490b70f..527976985a 100644 --- a/src/core/linux/SDL_udev.c +++ b/src/core/linux/SDL_udev.c @@ -167,6 +167,7 @@ void SDL_UDEV_Quit(void) { SDL_UDEV_CallbackList *item; + printf("We do indeed get here\n"); if (_this == NULL) { return; diff --git a/src/loadso/dlopen/SDL_sysloadso.c b/src/loadso/dlopen/SDL_sysloadso.c index 1b587d2a8b..061b1641c2 100644 --- a/src/loadso/dlopen/SDL_sysloadso.c +++ b/src/loadso/dlopen/SDL_sysloadso.c @@ -47,6 +47,7 @@ SDL_LoadObject(const char *sofile) } #endif + printf("SOFILE: %s\n", sofile); handle = dlopen(sofile, RTLD_NOW|RTLD_LOCAL); loaderror = (char *) dlerror(); if (handle == NULL) { diff --git a/src/video/SDL_egl.c b/src/video/SDL_egl.c index 9ccc2c3e1c..2cd3007ee5 100644 --- a/src/video/SDL_egl.c +++ b/src/video/SDL_egl.c @@ -177,6 +177,8 @@ static SDL_bool SDL_EGL_HasExtension(_THIS, SDL_EGL_ExtensionType type, const ch if (egl_extstr != NULL) { ext_start = egl_extstr; + printf("%s\n", ext_start); + while (*ext_start) { ext_start = SDL_strstr(ext_start, ext); if (ext_start == NULL) { diff --git a/src/video/wayland/SDL_waylandevents.c b/src/video/wayland/SDL_waylandevents.c index 961325fea7..32c7cdfdf2 100644 --- a/src/video/wayland/SDL_waylandevents.c +++ b/src/video/wayland/SDL_waylandevents.c @@ -366,6 +366,10 @@ static const struct wl_pointer_listener pointer_listener = { pointer_handle_motion, pointer_handle_button, pointer_handle_axis, + NULL, /* frame */ + NULL, /* axis_source */ + NULL, /* axis_stop */ + NULL, /* axis_discrete */ }; static void @@ -428,7 +432,9 @@ static const struct wl_touch_listener touch_listener = { touch_handler_up, touch_handler_motion, touch_handler_frame, - touch_handler_cancel + touch_handler_cancel, + NULL, /* shape */ + NULL, /* orientation */ }; static void @@ -564,6 +570,7 @@ static const struct wl_keyboard_listener keyboard_listener = { keyboard_handle_leave, keyboard_handle_key, keyboard_handle_modifiers, + NULL, /* repeat_info */ }; static void @@ -608,6 +615,7 @@ seat_handle_capabilities(void *data, struct wl_seat *seat, static const struct wl_seat_listener seat_listener = { seat_handle_capabilities, + NULL, /* name */ }; static void diff --git a/src/video/wayland/SDL_waylandvideo.c b/src/video/wayland/SDL_waylandvideo.c index e3a73bd3d7..7390ad6f22 100644 --- a/src/video/wayland/SDL_waylandvideo.c +++ b/src/video/wayland/SDL_waylandvideo.c @@ -344,7 +344,8 @@ display_handle_global(void *data, struct wl_registry *registry, uint32_t id, } static const struct wl_registry_listener registry_listener = { - display_handle_global + display_handle_global, + NULL, /* global_remove */ }; int diff --git a/test/configure b/test/configure index 61c32fba1b..d0e04b86e2 100755 --- a/test/configure +++ b/test/configure @@ -637,6 +637,7 @@ infodir docdir oldincludedir includedir +runstatedir localstatedir sharedstatedir sysconfdir @@ -717,6 +718,7 @@ datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' +runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE}' @@ -969,6 +971,15 @@ do | -silent | --silent | --silen | --sile | --sil) silent=yes ;; + -runstatedir | --runstatedir | --runstatedi | --runstated \ + | --runstate | --runstat | --runsta | --runst | --runs \ + | --run | --ru | --r) + ac_prev=runstatedir ;; + -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ + | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ + | --run=* | --ru=* | --r=*) + runstatedir=$ac_optarg ;; + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ @@ -1106,7 +1117,7 @@ fi for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir + libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. @@ -1259,6 +1270,7 @@ Fine tuning of the installation directories: --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] diff --git a/test/testgl2.c b/test/testgl2.c index 114c14105e..be64e3ad16 100644 --- a/test/testgl2.c +++ b/test/testgl2.c @@ -261,6 +261,8 @@ main(int argc, char *argv[]) state->gl_blue_size = 5; state->gl_depth_size = 16; state->gl_double_buffer = 1; + state->gl_major_version = 3; + state->gl_minor_version = 3; if (fsaa) { state->gl_multisamplebuffers = 1; state->gl_multisamplesamples = fsaa; From ea2b6392da39abf3f73a979b4bebc08cfca16184 Mon Sep 17 00:00:00 2001 From: Brandon Schaefer Date: Fri, 29 Sep 2017 10:15:44 -0700 Subject: [PATCH 24/95] revert files I didnt mean to commit! --- configure | 15 +- configure.in | 1 - include/SDL_config.h | 382 ++---------------------------- include/SDL_revision.h | 4 +- src/core/linux/SDL_udev.c | 1 - src/loadso/dlopen/SDL_sysloadso.c | 1 - src/video/SDL_egl.c | 2 - test/configure | 14 +- test/testgl2.c | 2 - 9 files changed, 25 insertions(+), 397 deletions(-) diff --git a/configure b/configure index 0b69f623e4..1cb707e2b7 100755 --- a/configure +++ b/configure @@ -745,7 +745,6 @@ infodir docdir oldincludedir includedir -runstatedir localstatedir sharedstatedir sysconfdir @@ -923,7 +922,6 @@ datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' -runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE}' @@ -1176,15 +1174,6 @@ do | -silent | --silent | --silen | --sile | --sil) silent=yes ;; - -runstatedir | --runstatedir | --runstatedi | --runstated \ - | --runstate | --runstat | --runsta | --runst | --runs \ - | --run | --ru | --r) - ac_prev=runstatedir ;; - -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ - | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ - | --run=* | --ru=* | --r=*) - runstatedir=$ac_optarg ;; - -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ @@ -1322,7 +1311,7 @@ fi for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir runstatedir + libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. @@ -1475,7 +1464,6 @@ Fine tuning of the installation directories: --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] - --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] @@ -19116,7 +19104,6 @@ $as_echo "$need_gcc_Wno_multichar" >&6; } CheckWayland() { - EXTRA_CFLAGS="$EXTRA_CFLAGS -Wall -Wmissing-field-initializers" # Check whether --enable-video-wayland was given. if test "${enable_video_wayland+set}" = set; then : enableval=$enable_video_wayland; diff --git a/configure.in b/configure.in index 6aa57d3dbb..33572d7a15 100644 --- a/configure.in +++ b/configure.in @@ -1366,7 +1366,6 @@ CheckWarnAll() dnl Check for Wayland CheckWayland() { - EXTRA_CFLAGS="$EXTRA_CFLAGS -Wall -Wmissing-field-initializers" AC_ARG_ENABLE(video-wayland, AC_HELP_STRING([--enable-video-wayland], [use Wayland video driver [[default=yes]]]), ,enable_video_wayland=yes) diff --git a/include/SDL_config.h b/include/SDL_config.h index 54d82244d2..41f5baabe5 100644 --- a/include/SDL_config.h +++ b/include/SDL_config.h @@ -1,4 +1,3 @@ -/* include/SDL_config.h. Generated from SDL_config.h.in by configure. */ /* Simple DirectMedia Layer Copyright (C) 1997-2017 Sam Lantinga @@ -23,371 +22,32 @@ #ifndef SDL_config_h_ #define SDL_config_h_ -/** - * \file SDL_config.h.in - * - * This is a set of defines to configure the SDL features - */ - -/* General platform specific identifiers */ #include "SDL_platform.h" -/* Make sure that this isn't included by Visual C++ */ -#ifdef _MSC_VER -#error You should run hg revert SDL_config.h -#endif - -/* C language features */ -/* #undef const */ -/* #undef inline */ -/* #undef volatile */ +/** + * \file SDL_config.h + */ -/* C datatypes */ -#ifdef __LP64__ -#define SIZEOF_VOIDP 8 +/* Add any platform that doesn't build using the configure system. */ +#if defined(__WIN32__) +#include "SDL_config_windows.h" +#elif defined(__WINRT__) +#include "SDL_config_winrt.h" +#elif defined(__MACOSX__) +#include "SDL_config_macosx.h" +#elif defined(__IPHONEOS__) +#include "SDL_config_iphoneos.h" +#elif defined(__ANDROID__) +#include "SDL_config_android.h" +#elif defined(__PSP__) +#include "SDL_config_psp.h" #else -#define SIZEOF_VOIDP 4 -#endif -#define HAVE_GCC_ATOMICS 1 -/* #undef HAVE_GCC_SYNC_LOCK_TEST_AND_SET */ +/* This is a minimal configuration just to get SDL running on new platforms */ +#include "SDL_config_minimal.h" +#endif /* platform config */ -/* Comment this if you want to build without any C library requirements */ -#define HAVE_LIBC 1 -#if HAVE_LIBC - -/* Useful headers */ -#define STDC_HEADERS 1 -#define HAVE_ALLOCA_H 1 -#define HAVE_CTYPE_H 1 -#define HAVE_FLOAT_H 1 -#define HAVE_ICONV_H 1 -#define HAVE_INTTYPES_H 1 -#define HAVE_LIMITS_H 1 -#define HAVE_MALLOC_H 1 -#define HAVE_MATH_H 1 -#define HAVE_MEMORY_H 1 -#define HAVE_SIGNAL_H 1 -#define HAVE_STDARG_H 1 -#define HAVE_STDINT_H 1 -#define HAVE_STDIO_H 1 -#define HAVE_STDLIB_H 1 -#define HAVE_STRINGS_H 1 -#define HAVE_STRING_H 1 -#define HAVE_SYS_TYPES_H 1 -#define HAVE_WCHAR_H 1 -/* #undef HAVE_PTHREAD_NP_H */ - -/* C library functions */ -#define HAVE_MALLOC 1 -#define HAVE_CALLOC 1 -#define HAVE_REALLOC 1 -#define HAVE_FREE 1 -#define HAVE_ALLOCA 1 -#ifndef __WIN32__ /* Don't use C runtime versions of these on Windows */ -#define HAVE_GETENV 1 -#define HAVE_SETENV 1 -#define HAVE_PUTENV 1 -#define HAVE_UNSETENV 1 +#ifdef USING_GENERATED_CONFIG_H +#error Wrong SDL_config.h, check your include path? #endif -#define HAVE_QSORT 1 -#define HAVE_ABS 1 -#define HAVE_BCOPY 1 -#define HAVE_MEMSET 1 -#define HAVE_MEMCPY 1 -#define HAVE_MEMMOVE 1 -#define HAVE_MEMCMP 1 -#define HAVE_WCSLEN 1 -/* #undef HAVE_WCSLCPY */ -/* #undef HAVE_WCSLCAT */ -#define HAVE_WCSCMP 1 -#define HAVE_STRLEN 1 -/* #undef HAVE_STRLCPY */ -/* #undef HAVE_STRLCAT */ -#define HAVE_STRDUP 1 -/* #undef HAVE__STRREV */ -/* #undef HAVE__STRUPR */ -/* #undef HAVE__STRLWR */ -/* #undef HAVE_INDEX */ -/* #undef HAVE_RINDEX */ -#define HAVE_STRCHR 1 -#define HAVE_STRRCHR 1 -#define HAVE_STRSTR 1 -/* #undef HAVE_ITOA */ -/* #undef HAVE__LTOA */ -/* #undef HAVE__UITOA */ -/* #undef HAVE__ULTOA */ -#define HAVE_STRTOL 1 -#define HAVE_STRTOUL 1 -/* #undef HAVE__I64TOA */ -/* #undef HAVE__UI64TOA */ -#define HAVE_STRTOLL 1 -#define HAVE_STRTOULL 1 -#define HAVE_STRTOD 1 -#define HAVE_ATOI 1 -#define HAVE_ATOF 1 -#define HAVE_STRCMP 1 -#define HAVE_STRNCMP 1 -/* #undef HAVE__STRICMP */ -#define HAVE_STRCASECMP 1 -/* #undef HAVE__STRNICMP */ -#define HAVE_STRNCASECMP 1 -/* #undef HAVE_SSCANF */ -#define HAVE_VSSCANF 1 -/* #undef HAVE_SNPRINTF */ -#define HAVE_VSNPRINTF 1 -#define HAVE_M_PI /**/ -#define HAVE_ATAN 1 -#define HAVE_ATAN2 1 -#define HAVE_ACOS 1 -#define HAVE_ASIN 1 -#define HAVE_CEIL 1 -#define HAVE_COPYSIGN 1 -#define HAVE_COS 1 -#define HAVE_COSF 1 -#define HAVE_FABS 1 -#define HAVE_FLOOR 1 -#define HAVE_LOG 1 -#define HAVE_POW 1 -#define HAVE_SCALBN 1 -#define HAVE_SIN 1 -#define HAVE_SINF 1 -#define HAVE_SQRT 1 -#define HAVE_SQRTF 1 -#define HAVE_TAN 1 -#define HAVE_TANF 1 -#define HAVE_FOPEN64 1 -#define HAVE_FSEEKO 1 -#define HAVE_FSEEKO64 1 -#define HAVE_SIGACTION 1 -#define HAVE_SA_SIGACTION 1 -#define HAVE_SETJMP 1 -#define HAVE_NANOSLEEP 1 -#define HAVE_SYSCONF 1 -/* #undef HAVE_SYSCTLBYNAME */ -#define HAVE_CLOCK_GETTIME 1 -/* #undef HAVE_GETPAGESIZE */ -#define HAVE_MPROTECT 1 -#define HAVE_ICONV 1 -#define HAVE_PTHREAD_SETNAME_NP 1 -/* #undef HAVE_PTHREAD_SET_NAME_NP */ -#define HAVE_SEM_TIMEDWAIT 1 -#define HAVE_GETAUXVAL 1 -#define HAVE_POLL 1 - -#else -#define HAVE_STDARG_H 1 -#define HAVE_STDDEF_H 1 -#define HAVE_STDINT_H 1 -#endif /* HAVE_LIBC */ - -/* #undef HAVE_ALTIVEC_H */ -#define HAVE_LIBUDEV_H 1 -#define HAVE_DBUS_DBUS_H 1 -#define HAVE_IBUS_IBUS_H 1 -/* #undef HAVE_FCITX_FRONTEND_H */ -#define HAVE_LIBSAMPLERATE_H 1 - -/* #undef HAVE_DDRAW_H */ -/* #undef HAVE_DINPUT_H */ -/* #undef HAVE_DSOUND_H */ -/* #undef HAVE_DXGI_H */ -/* #undef HAVE_XINPUT_H */ -/* #undef HAVE_XINPUT_GAMEPAD_EX */ -/* #undef HAVE_XINPUT_STATE_EX */ - -/* SDL internal assertion support */ -/* #undef SDL_DEFAULT_ASSERT_LEVEL */ - -/* Allow disabling of core subsystems */ -/* #undef SDL_ATOMIC_DISABLED */ -/* #undef SDL_AUDIO_DISABLED */ -/* #undef SDL_CPUINFO_DISABLED */ -/* #undef SDL_EVENTS_DISABLED */ -/* #undef SDL_FILE_DISABLED */ -/* #undef SDL_JOYSTICK_DISABLED */ -/* #undef SDL_HAPTIC_DISABLED */ -/* #undef SDL_LOADSO_DISABLED */ -/* #undef SDL_RENDER_DISABLED */ -/* #undef SDL_THREADS_DISABLED */ -/* #undef SDL_TIMERS_DISABLED */ -/* #undef SDL_VIDEO_DISABLED */ -/* #undef SDL_POWER_DISABLED */ -/* #undef SDL_FILESYSTEM_DISABLED */ - -/* Enable various audio drivers */ -#define SDL_AUDIO_DRIVER_ALSA 1 -#define SDL_AUDIO_DRIVER_ALSA_DYNAMIC "libasound.so.2" -/* #undef SDL_AUDIO_DRIVER_ANDROID */ -/* #undef SDL_AUDIO_DRIVER_ARTS */ -/* #undef SDL_AUDIO_DRIVER_ARTS_DYNAMIC */ -/* #undef SDL_AUDIO_DRIVER_COREAUDIO */ -#define SDL_AUDIO_DRIVER_DISK 1 -/* #undef SDL_AUDIO_DRIVER_DSOUND */ -#define SDL_AUDIO_DRIVER_DUMMY 1 -/* #undef SDL_AUDIO_DRIVER_EMSCRIPTEN */ -/* #undef SDL_AUDIO_DRIVER_ESD */ -/* #undef SDL_AUDIO_DRIVER_ESD_DYNAMIC */ -/* #undef SDL_AUDIO_DRIVER_FUSIONSOUND */ -/* #undef SDL_AUDIO_DRIVER_FUSIONSOUND_DYNAMIC */ -/* #undef SDL_AUDIO_DRIVER_HAIKU */ -#define SDL_AUDIO_DRIVER_JACK 1 -#define SDL_AUDIO_DRIVER_JACK_DYNAMIC "libjack.so.0" -/* #undef SDL_AUDIO_DRIVER_NACL */ -/* #undef SDL_AUDIO_DRIVER_NAS */ -/* #undef SDL_AUDIO_DRIVER_NAS_DYNAMIC */ -/* #undef SDL_AUDIO_DRIVER_NETBSD */ -#define SDL_AUDIO_DRIVER_OSS 1 -/* #undef SDL_AUDIO_DRIVER_OSS_SOUNDCARD_H */ -/* #undef SDL_AUDIO_DRIVER_PAUDIO */ -#define SDL_AUDIO_DRIVER_PULSEAUDIO 1 -#define SDL_AUDIO_DRIVER_PULSEAUDIO_DYNAMIC "libpulse-simple.so.0" -/* #undef SDL_AUDIO_DRIVER_QSA */ -#define SDL_AUDIO_DRIVER_SNDIO 1 -/* #undef SDL_AUDIO_DRIVER_SNDIO_DYNAMIC */ -/* #undef SDL_AUDIO_DRIVER_SUNAUDIO */ -/* #undef SDL_AUDIO_DRIVER_WASAPI */ -/* #undef SDL_AUDIO_DRIVER_WINMM */ -/* #undef SDL_AUDIO_DRIVER_XAUDIO2 */ - -/* Enable various input drivers */ -#define SDL_INPUT_LINUXEV 1 -#define SDL_INPUT_LINUXKD 1 -/* #undef SDL_INPUT_TSLIB */ -/* #undef SDL_JOYSTICK_HAIKU */ -/* #undef SDL_JOYSTICK_DINPUT */ -/* #undef SDL_JOYSTICK_XINPUT */ -/* #undef SDL_JOYSTICK_DUMMY */ -/* #undef SDL_JOYSTICK_IOKIT */ -#define SDL_JOYSTICK_LINUX 1 -/* #undef SDL_JOYSTICK_ANDROID */ -/* #undef SDL_JOYSTICK_WINMM */ -/* #undef SDL_JOYSTICK_USBHID */ -/* #undef SDL_JOYSTICK_USBHID_MACHINE_JOYSTICK_H */ -/* #undef SDL_JOYSTICK_EMSCRIPTEN */ -/* #undef SDL_HAPTIC_DUMMY */ -#define SDL_HAPTIC_LINUX 1 -/* #undef SDL_HAPTIC_IOKIT */ -/* #undef SDL_HAPTIC_DINPUT */ -/* #undef SDL_HAPTIC_XINPUT */ - -/* Enable various shared object loading systems */ -#define SDL_LOADSO_DLOPEN 1 -/* #undef SDL_LOADSO_DUMMY */ -/* #undef SDL_LOADSO_LDG */ -/* #undef SDL_LOADSO_WINDOWS */ - -/* Enable various threading systems */ -#define SDL_THREAD_PTHREAD 1 -#define SDL_THREAD_PTHREAD_RECURSIVE_MUTEX 1 -/* #undef SDL_THREAD_PTHREAD_RECURSIVE_MUTEX_NP */ -/* #undef SDL_THREAD_WINDOWS */ - -/* Enable various timer systems */ -/* #undef SDL_TIMER_HAIKU */ -/* #undef SDL_TIMER_DUMMY */ -#define SDL_TIMER_UNIX 1 -/* #undef SDL_TIMER_WINDOWS */ - -/* Enable various video drivers */ -/* #undef SDL_VIDEO_DRIVER_HAIKU */ -/* #undef SDL_VIDEO_DRIVER_COCOA */ -/* #undef SDL_VIDEO_DRIVER_DIRECTFB */ -/* #undef SDL_VIDEO_DRIVER_DIRECTFB_DYNAMIC */ -#define SDL_VIDEO_DRIVER_DUMMY 1 -/* #undef SDL_VIDEO_DRIVER_WINDOWS */ -#define SDL_VIDEO_DRIVER_WAYLAND 1 -#define SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH 1 -#define SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC "libwayland-client.so.0" -#define SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_EGL "libwayland-egl.so.1" -#define SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_CURSOR "libwayland-cursor.so.0" -#define SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_XKBCOMMON "libxkbcommon.so.0" -/* #undef SDL_VIDEO_DRIVER_MIR */ -/* #undef SDL_VIDEO_DRIVER_MIR_DYNAMIC */ -/* #undef SDL_VIDEO_DRIVER_MIR_DYNAMIC_XKBCOMMON */ -#define SDL_VIDEO_DRIVER_X11 1 -/* #undef SDL_VIDEO_DRIVER_RPI */ -/* #undef SDL_VIDEO_DRIVER_KMSDRM */ -/* #undef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC */ -/* #undef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC_GBM */ -/* #undef SDL_VIDEO_DRIVER_ANDROID */ -/* #undef SDL_VIDEO_DRIVER_EMSCRIPTEN */ -#define SDL_VIDEO_DRIVER_X11_DYNAMIC "libX11.so.6" -#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT "libXext.so.6" -#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XCURSOR "libXcursor.so.1" -#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XINERAMA "libXinerama.so.1" -#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT2 "libXi.so.6" -#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR "libXrandr.so.2" -#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS "libXss.so.1" -#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XVIDMODE "libXxf86vm.so.1" -#define SDL_VIDEO_DRIVER_X11_XCURSOR 1 -#define SDL_VIDEO_DRIVER_X11_XDBE 1 -#define SDL_VIDEO_DRIVER_X11_XINERAMA 1 -#define SDL_VIDEO_DRIVER_X11_XINPUT2 1 -#define SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH 1 -#define SDL_VIDEO_DRIVER_X11_XRANDR 1 -#define SDL_VIDEO_DRIVER_X11_XSCRNSAVER 1 -#define SDL_VIDEO_DRIVER_X11_XSHAPE 1 -#define SDL_VIDEO_DRIVER_X11_XVIDMODE 1 -#define SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS 1 -#define SDL_VIDEO_DRIVER_X11_CONST_PARAM_XEXTADDDISPLAY 1 -#define SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM 1 -/* #undef SDL_VIDEO_DRIVER_NACL */ -/* #undef SDL_VIDEO_DRIVER_VIVANTE */ -/* #undef SDL_VIDEO_DRIVER_VIVANTE_VDK */ -/* #undef SDL_VIDEO_DRIVER_QNX */ - -/* #undef SDL_VIDEO_RENDER_D3D */ -/* #undef SDL_VIDEO_RENDER_D3D11 */ -#define SDL_VIDEO_RENDER_OGL 1 -/* #undef SDL_VIDEO_RENDER_OGL_ES */ -#define SDL_VIDEO_RENDER_OGL_ES2 1 -/* #undef SDL_VIDEO_RENDER_DIRECTFB */ - -/* Enable OpenGL support */ -#define SDL_VIDEO_OPENGL 1 -/* #undef SDL_VIDEO_OPENGL_ES */ -#define SDL_VIDEO_OPENGL_ES2 1 -/* #undef SDL_VIDEO_OPENGL_BGL */ -/* #undef SDL_VIDEO_OPENGL_CGL */ -#define SDL_VIDEO_OPENGL_EGL 1 -#define SDL_VIDEO_OPENGL_GLX 1 -/* #undef SDL_VIDEO_OPENGL_WGL */ -/* #undef SDL_VIDEO_OPENGL_OSMESA */ -/* #undef SDL_VIDEO_OPENGL_OSMESA_DYNAMIC */ - -/* Enable Vulkan support */ -#define SDL_VIDEO_VULKAN 1 - -/* Enable system power support */ -#define SDL_POWER_LINUX 1 -/* #undef SDL_POWER_WINDOWS */ -/* #undef SDL_POWER_MACOSX */ -/* #undef SDL_POWER_HAIKU */ -/* #undef SDL_POWER_ANDROID */ -/* #undef SDL_POWER_EMSCRIPTEN */ -/* #undef SDL_POWER_HARDWIRED */ - -/* Enable system filesystem support */ -/* #undef SDL_FILESYSTEM_HAIKU */ -/* #undef SDL_FILESYSTEM_COCOA */ -/* #undef SDL_FILESYSTEM_DUMMY */ -#define SDL_FILESYSTEM_UNIX 1 -/* #undef SDL_FILESYSTEM_WINDOWS */ -/* #undef SDL_FILESYSTEM_NACL */ -/* #undef SDL_FILESYSTEM_ANDROID */ -/* #undef SDL_FILESYSTEM_EMSCRIPTEN */ - -/* Enable assembly routines */ -#define SDL_ASSEMBLY_ROUTINES 1 -/* #undef SDL_ALTIVEC_BLITTERS */ - -/* Enable ime support */ -#define SDL_USE_IME 1 - -/* Enable dynamic udev support */ -#define SDL_UDEV_DYNAMIC "libudev.so.1" - -/* Enable dynamic libsamplerate support */ -#define SDL_LIBSAMPLERATE_DYNAMIC "libsamplerate.so.0" #endif /* SDL_config_h_ */ diff --git a/include/SDL_revision.h b/include/SDL_revision.h index ecd1d57282..d70fd694ea 100644 --- a/include/SDL_revision.h +++ b/include/SDL_revision.h @@ -1,2 +1,2 @@ -#define SDL_REVISION "hg-11511:833d4fbb3d76" -#define SDL_REVISION_NUMBER 11511 +#define SDL_REVISION "hg-0:aaaaaaaaaaah" +#define SDL_REVISION_NUMBER 0 diff --git a/src/core/linux/SDL_udev.c b/src/core/linux/SDL_udev.c index 527976985a..502490b70f 100644 --- a/src/core/linux/SDL_udev.c +++ b/src/core/linux/SDL_udev.c @@ -167,7 +167,6 @@ void SDL_UDEV_Quit(void) { SDL_UDEV_CallbackList *item; - printf("We do indeed get here\n"); if (_this == NULL) { return; diff --git a/src/loadso/dlopen/SDL_sysloadso.c b/src/loadso/dlopen/SDL_sysloadso.c index 061b1641c2..1b587d2a8b 100644 --- a/src/loadso/dlopen/SDL_sysloadso.c +++ b/src/loadso/dlopen/SDL_sysloadso.c @@ -47,7 +47,6 @@ SDL_LoadObject(const char *sofile) } #endif - printf("SOFILE: %s\n", sofile); handle = dlopen(sofile, RTLD_NOW|RTLD_LOCAL); loaderror = (char *) dlerror(); if (handle == NULL) { diff --git a/src/video/SDL_egl.c b/src/video/SDL_egl.c index 2cd3007ee5..9ccc2c3e1c 100644 --- a/src/video/SDL_egl.c +++ b/src/video/SDL_egl.c @@ -177,8 +177,6 @@ static SDL_bool SDL_EGL_HasExtension(_THIS, SDL_EGL_ExtensionType type, const ch if (egl_extstr != NULL) { ext_start = egl_extstr; - printf("%s\n", ext_start); - while (*ext_start) { ext_start = SDL_strstr(ext_start, ext); if (ext_start == NULL) { diff --git a/test/configure b/test/configure index d0e04b86e2..61c32fba1b 100755 --- a/test/configure +++ b/test/configure @@ -637,7 +637,6 @@ infodir docdir oldincludedir includedir -runstatedir localstatedir sharedstatedir sysconfdir @@ -718,7 +717,6 @@ datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' -runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE}' @@ -971,15 +969,6 @@ do | -silent | --silent | --silen | --sile | --sil) silent=yes ;; - -runstatedir | --runstatedir | --runstatedi | --runstated \ - | --runstate | --runstat | --runsta | --runst | --runs \ - | --run | --ru | --r) - ac_prev=runstatedir ;; - -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ - | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ - | --run=* | --ru=* | --r=*) - runstatedir=$ac_optarg ;; - -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ @@ -1117,7 +1106,7 @@ fi for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir runstatedir + libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. @@ -1270,7 +1259,6 @@ Fine tuning of the installation directories: --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] - --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] diff --git a/test/testgl2.c b/test/testgl2.c index be64e3ad16..114c14105e 100644 --- a/test/testgl2.c +++ b/test/testgl2.c @@ -261,8 +261,6 @@ main(int argc, char *argv[]) state->gl_blue_size = 5; state->gl_depth_size = 16; state->gl_double_buffer = 1; - state->gl_major_version = 3; - state->gl_minor_version = 3; if (fsaa) { state->gl_multisamplebuffers = 1; state->gl_multisamplesamples = fsaa; From f4de360db12f78d1307301113f1902eb06ce5610 Mon Sep 17 00:00:00 2001 From: Brandon Schaefer Date: Mon, 2 Oct 2017 10:50:33 -0700 Subject: [PATCH 25/95] Fixed bug 3855 - Memory leak in SDL_FreeSurface --- src/video/SDL_surface.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/video/SDL_surface.c b/src/video/SDL_surface.c index 75b699c3a0..cabe7e0931 100644 --- a/src/video/SDL_surface.c +++ b/src/video/SDL_surface.c @@ -1217,6 +1217,9 @@ SDL_FreeSurface(SDL_Surface * surface) if (!(surface->flags & SDL_PREALLOC)) { SDL_free(surface->pixels); } + if (surface->map) { + SDL_FreeBlitMap(surface->map); + } SDL_free(surface); } From 6a2fd6eb1c27a65881b8129998bcb2059c440eae Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 5 Oct 2017 09:37:28 -0700 Subject: [PATCH 26/95] Fixed bug 3854 - arguments to dbus_type_is_basic() were incorrect Aaron As of 2.0.6, all of my games are failing with the following error: process 31778: arguments to dbus_type_is_basic() were incorrect, assertion "dbus_type_is_valid (typecode) || typecode == DBUS_TYPE_INVALID" failed in file dbus-signature.c line 322. This is normally a bug in some application using the D-Bus library. D-Bus not built with -rdynamic so unable to print a backtrace (patch by Ozkan Sezer) --- src/core/linux/SDL_ibus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/linux/SDL_ibus.c b/src/core/linux/SDL_ibus.c index 0fcec87a11..f537380963 100644 --- a/src/core/linux/SDL_ibus.c +++ b/src/core/linux/SDL_ibus.c @@ -479,7 +479,7 @@ IBus_SimpleMessage(const char *method) SDL_DBusContext *dbus = SDL_DBus_GetContext(); if (IBus_CheckConnection(dbus)) { - SDL_DBus_CallVoidMethodOnConnection(ibus_conn, IBUS_SERVICE, input_ctx_path, IBUS_INPUT_INTERFACE, method); + SDL_DBus_CallVoidMethodOnConnection(ibus_conn, IBUS_SERVICE, input_ctx_path, IBUS_INPUT_INTERFACE, method, DBUS_TYPE_INVALID); } } From 4e9f3f3db77b628e53f672ac91a3bcd746ffb787 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 6 Oct 2017 16:17:50 -0700 Subject: [PATCH 27/95] Fixed potential overflow in surface allocation (thanks Yves!) --- src/video/SDL_surface.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/video/SDL_surface.c b/src/video/SDL_surface.c index cabe7e0931..721c477402 100644 --- a/src/video/SDL_surface.c +++ b/src/video/SDL_surface.c @@ -80,7 +80,15 @@ SDL_CreateRGBSurfaceWithFormat(Uint32 flags, int width, int height, int depth, /* Get the pixels */ if (surface->w && surface->h) { - surface->pixels = SDL_malloc(surface->h * surface->pitch); + int size = (surface->h * surface->pitch); + if (size < 0 || (size / surface->pitch) != surface->h) { + /* Overflow... */ + SDL_FreeSurface(surface); + SDL_OutOfMemory(); + return NULL; + } + + surface->pixels = SDL_malloc(size); if (!surface->pixels) { SDL_FreeSurface(surface); SDL_OutOfMemory(); From 78f84b0f91cfb90994b678b3d0001442f6af5f76 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 6 Oct 2017 16:42:43 -0700 Subject: [PATCH 28/95] Fixed bug 3862 - Install is broken when adding SDL2 to an existing CMake project Steve Robinson In my existing CMake project, I use add_subdirectory to add the source for SDL2. This worked fine in 2.0.5, but now in 2.0.6 when I build the INSTALL CMake target, I get this error: file INSTALL cannot find "D:/path/to/SDL2Config.cmake". Call Stack (most recent call first): 3rdparty/SDL2/cmake_install.cmake:32 (include) 3rdparty/cmake_install.cmake:36 (include) cmake_install.cmake:32 (include) To fix this, I changed line 1770 from this: ${CMAKE_SOURCE_DIR}/SDL2Config.cmake To this: ${CMAKE_CURRENT_SOURCE_DIR}/SDL2Config.cmake --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 33a3f6c5ca..9d363aec0d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1767,7 +1767,7 @@ install(EXPORT SDL2Targets ) install( FILES - ${CMAKE_SOURCE_DIR}/SDL2Config.cmake + ${CMAKE_CURRENT_SOURCE_DIR}/SDL2Config.cmake ${CMAKE_BINARY_DIR}/SDL2ConfigVersion.cmake DESTINATION ${PKG_PREFIX} COMPONENT Devel From 4993f7760b1b85206d2b55a62bd046a36f58ed61 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 6 Oct 2017 16:50:24 -0700 Subject: [PATCH 29/95] Fixed bug 3857 - SDL_ConvertPixels misses YUV conversions Sylvain Few issues with YUV on SDL2 when using odd dimensions, and missing conversions from/back to YUV formats. 1) The big part is that SDL_ConvertPixels() does not convert to/from YUV in most cases. This now works with any format and also with odd dimensions, by adding two internal functions SDL_ConvertPixels_YUV_to_ARGB8888 and SDL_ConvertPixels_ARGB8888_to_YUV (could it be XRGB888 ?). The target format is hard coded to ARGB888 (which is the default in the internal of the software renderer). In case of different YUV conversion, it will do an intermediate conversion to a ARGB8888 buffer. SDL_ConvertPixels_YUV_to_ARGB8888 is somehow redundant with all the "Color*Dither*Mod*". But it allows some completeness of SDL_ConvertPixels to handle all YUV format. It also works with odd dimensions. Moreover, I did some benchmark(SDL_ConvertPixel vs Color32DitherYV12Mod1X and Color32DitherYUY2Mod1X). gcc-6.3 and clang-4.0. gcc performs better than clang. And, with gcc, SDL_ConvertPixels() performs better (20%) than the two C function Color32Dither*(). For instance, to convert 10 times a 3888x2592 image, it takes ~195 ms with SDL_ConvertPixels and ~235 ms with Color32Dither*(). Especially because of gcc vectorize feature that optimises all conversion loops (-ftree-loop-vectorize). Nb: I put no image pitch for the YUV buffers. because it complexify a little bit the code and the API : There would be some ambiguity when setting the pitch exactly to image width: would it a be pitch of image width (for luma and chroma). or just contiguous data ? (could set pitch=0 for the later). 2) Small issues with odd dimensions: If width "w" is odd, luma plane width is still "w" whereas chroma planes will be "(w + 1)/2". Almost the same for odd h. Solution is to strategically substitute "w" by "(w+1)/2" at the good places ... - In the repository, SDL_ConvertPixels() handles YUV only if yuv source format is exactly the same as YUV destination format. It basically does a memcpy of pixels, but it's done incorrectly when width or height is odd (wrong size of chroma planes). This is fixed. - SDL Renderers don't support odd width/height for YUV textures. This is fixed for software, opengl, opengles2. (opengles 1 does not support it and fallback to software rendering). This is *not* fixed for D3D and D3D11 ... (and others, psp ?) Only *two* Dither function are fixed ... not sure if others are really used. - This is not possible to create a NV12/NV12 texture with the software renderer, whereas other renderers allow it. This is fixed, by using SDL_ConvertPixels underneath. - It was not possible to SDL_UpdateTexture() of format NV12/NV21 with the software renderer. this is fixed. Here's also two testcases: - that do all combination of conversion. - to test partial UpdateTexture --- src/render/SDL_yuv_sw.c | 185 +++++-- src/render/opengl/SDL_render_gl.c | 32 +- src/render/opengles2/SDL_render_gles2.c | 39 +- src/video/SDL_surface.c | 608 ++++++++++++++++++++++-- 4 files changed, 767 insertions(+), 97 deletions(-) diff --git a/src/render/SDL_yuv_sw.c b/src/render/SDL_yuv_sw.c index 9d202e0e7f..49fce6db2c 100644 --- a/src/render/SDL_yuv_sw.c +++ b/src/render/SDL_yuv_sw.c @@ -265,7 +265,18 @@ Color32DitherYV12Mod1X(int *colortab, Uint32 * rgb_2_pix, int cr_r; int crb_g; int cb_b; - int cols_2 = cols / 2; + int cols_2 = (cols + 1) / 2; + /* not even dimensions */ + int skip_last_col = 0; + int skip_last_row = 0; + + if ( (cols & 0x1) ) { + skip_last_col = 1; + } + + if ( (rows & 0x1) ) { + skip_last_row = 1; + } row1 = (unsigned int *) out; row2 = row1 + cols + mod; @@ -273,7 +284,7 @@ Color32DitherYV12Mod1X(int *colortab, Uint32 * rgb_2_pix, mod += cols + mod; - y = rows / 2; + y = (rows + 1) / 2; while (y--) { x = cols_2; while (x--) { @@ -290,20 +301,27 @@ Color32DitherYV12Mod1X(int *colortab, Uint32 * rgb_2_pix, *row1++ = (rgb_2_pix[L + cr_r] | rgb_2_pix[L + crb_g] | rgb_2_pix[L + cb_b]); + if (!(x == 0 && skip_last_col)) { L = *lum++; *row1++ = (rgb_2_pix[L + cr_r] | rgb_2_pix[L + crb_g] | rgb_2_pix[L + cb_b]); + } /* skip col */ + if (!(y == 0 && skip_last_row)) { + /* Now, do second row. */ L = *lum2++; *row2++ = (rgb_2_pix[L + cr_r] | rgb_2_pix[L + crb_g] | rgb_2_pix[L + cb_b]); + if (!(x == 1 && skip_last_col)) { L = *lum2++; *row2++ = (rgb_2_pix[L + cr_r] | rgb_2_pix[L + crb_g] | rgb_2_pix[L + cb_b]); + } /* skip col */ + } /* skip row */ } /* @@ -670,7 +688,12 @@ Color32DitherYUY2Mod1X(int *colortab, Uint32 * rgb_2_pix, int cr_r; int crb_g; int cb_b; - int cols_2 = cols / 2; + int cols_2 = (cols + 1) / 2; + /* not even dimensions */ + int skip_last_col = 0; + if ( (cols & 0x1) ) { + skip_last_col = 1; + } row = (unsigned int *) out; y = rows; @@ -693,9 +716,11 @@ Color32DitherYUY2Mod1X(int *colortab, Uint32 * rgb_2_pix, L = *lum; lum += 2; + + if (!(x == 0 && skip_last_col)) { *row++ = (rgb_2_pix[L + cr_r] | rgb_2_pix[L + crb_g] | rgb_2_pix[L + cb_b]); - + } /* skip col */ } row += mod; @@ -1022,6 +1047,13 @@ SDL_SW_SetupYUVDisplay(SDL_SW_YUVTexture * swdata, Uint32 target_format) swdata->Display2X = Color32DitherYUY2Mod2X; } break; + case SDL_PIXELFORMAT_NV21: + case SDL_PIXELFORMAT_NV12: + /* no Display{1,2}X function */ + swdata->Display1X = NULL; + swdata->Display2X = NULL; + break; + default: /* We should never get here (caught above) */ break; @@ -1049,6 +1081,8 @@ SDL_SW_CreateYUVTexture(Uint32 format, int w, int h) case SDL_PIXELFORMAT_YUY2: case SDL_PIXELFORMAT_UYVY: case SDL_PIXELFORMAT_YVYU: + case SDL_PIXELFORMAT_NV12: + case SDL_PIXELFORMAT_NV21: break; default: SDL_SetError("Unsupported YUV format"); @@ -1065,7 +1099,35 @@ SDL_SW_CreateYUVTexture(Uint32 format, int w, int h) swdata->target_format = SDL_PIXELFORMAT_UNKNOWN; swdata->w = w; swdata->h = h; - swdata->pixels = (Uint8 *) SDL_malloc(w * h * 2); + { + const int sz_plane = w * h; + const int sz_plane_chroma = ((w + 1) / 2) * ((h + 1) / 2); + const int sz_plane_packed = ((w + 1) / 2) * h; + int dst_size = 0; + switch(format) + { + case SDL_PIXELFORMAT_YV12: /**< Planar mode: Y + V + U (3 planes) */ + case SDL_PIXELFORMAT_IYUV: /**< Planar mode: Y + U + V (3 planes) */ + dst_size = sz_plane + sz_plane_chroma + sz_plane_chroma; + break; + + case SDL_PIXELFORMAT_YUY2: /**< Packed mode: Y0+U0+Y1+V0 (1 plane) */ + case SDL_PIXELFORMAT_UYVY: /**< Packed mode: U0+Y0+V0+Y1 (1 plane) */ + case SDL_PIXELFORMAT_YVYU: /**< Packed mode: Y0+V0+Y1+U0 (1 plane) */ + dst_size = 4 * sz_plane_packed; + break; + + case SDL_PIXELFORMAT_NV12: /**< Planar mode: Y + U/V interleaved (2 planes) */ + case SDL_PIXELFORMAT_NV21: /**< Planar mode: Y + V/U interleaved (2 planes) */ + dst_size = sz_plane + sz_plane_chroma + sz_plane_chroma; + break; + + default: + SDL_assert(0 && "We should never get here (caught above)"); + break; + } + swdata->pixels = (Uint8 *) SDL_malloc(dst_size); + } swdata->colortab = (int *) SDL_malloc(4 * 256 * sizeof(int)); swdata->rgb_2_pix = (Uint32 *) SDL_malloc(3 * 768 * sizeof(Uint32)); if (!swdata->pixels || !swdata->colortab || !swdata->rgb_2_pix) { @@ -1095,18 +1157,27 @@ SDL_SW_CreateYUVTexture(Uint32 format, int w, int h) case SDL_PIXELFORMAT_YV12: case SDL_PIXELFORMAT_IYUV: swdata->pitches[0] = w; - swdata->pitches[1] = swdata->pitches[0] / 2; - swdata->pitches[2] = swdata->pitches[0] / 2; + swdata->pitches[1] = (swdata->pitches[0] + 1) / 2; + swdata->pitches[2] = (swdata->pitches[0] + 1) / 2; swdata->planes[0] = swdata->pixels; swdata->planes[1] = swdata->planes[0] + swdata->pitches[0] * h; - swdata->planes[2] = swdata->planes[1] + swdata->pitches[1] * h / 2; + swdata->planes[2] = swdata->planes[1] + swdata->pitches[1] * ((h + 1) / 2); break; case SDL_PIXELFORMAT_YUY2: case SDL_PIXELFORMAT_UYVY: case SDL_PIXELFORMAT_YVYU: - swdata->pitches[0] = w * 2; + swdata->pitches[0] = ((w + 1) / 2) * 4; swdata->planes[0] = swdata->pixels; break; + + case SDL_PIXELFORMAT_NV12: + case SDL_PIXELFORMAT_NV21: + swdata->pitches[0] = w; + swdata->pitches[1] = 2 * ((swdata->pitches[0] + 1) / 2); + swdata->planes[0] = swdata->pixels; + swdata->planes[1] = swdata->planes[0] + swdata->pitches[0] * h; + break; + default: SDL_assert(0 && "We should never get here (caught above)"); break; @@ -1135,7 +1206,7 @@ SDL_SW_UpdateYUVTexture(SDL_SW_YUVTexture * swdata, const SDL_Rect * rect, if (rect->x == 0 && rect->y == 0 && rect->w == swdata->w && rect->h == swdata->h) { SDL_memcpy(swdata->pixels, pixels, - (swdata->h * swdata->w) + (swdata->h * swdata->w) / 2); + (swdata->h * swdata->w) + 2* ((swdata->h + 1) /2) * ((swdata->w + 1) / 2)); } else { Uint8 *src, *dst; int row; @@ -1150,28 +1221,28 @@ SDL_SW_UpdateYUVTexture(SDL_SW_YUVTexture * swdata, const SDL_Rect * rect, src += pitch; dst += swdata->w; } - + /* Copy the next plane */ src = (Uint8 *) pixels + rect->h * pitch; dst = swdata->pixels + swdata->h * swdata->w; - dst += rect->y/2 * swdata->w/2 + rect->x/2; - length = rect->w / 2; - for (row = 0; row < rect->h/2; ++row) { + dst += rect->y/2 * ((swdata->w + 1) / 2) + rect->x/2; + length = (rect->w + 1) / 2; + for (row = 0; row < (rect->h + 1)/2; ++row) { SDL_memcpy(dst, src, length); - src += pitch/2; - dst += swdata->w/2; + src += (pitch + 1)/2; + dst += (swdata->w + 1)/2; } /* Copy the next plane */ - src = (Uint8 *) pixels + rect->h * pitch + (rect->h * pitch) / 4; + src = (Uint8 *) pixels + rect->h * pitch + ((rect->h + 1) / 2) * ((pitch + 1) / 2); dst = swdata->pixels + swdata->h * swdata->w + - (swdata->h * swdata->w) / 4; - dst += rect->y/2 * swdata->w/2 + rect->x/2; - length = rect->w / 2; - for (row = 0; row < rect->h/2; ++row) { + ((swdata->h + 1)/2) * ((swdata->w+1) / 2); + dst += rect->y/2 * ((swdata->w + 1)/2) + rect->x/2; + length = (rect->w + 1) / 2; + for (row = 0; row < (rect->h + 1)/2; ++row) { SDL_memcpy(dst, src, length); - src += pitch/2; - dst += swdata->w/2; + src += (pitch + 1)/2; + dst += (swdata->w + 1)/2; } } break; @@ -1187,7 +1258,7 @@ SDL_SW_UpdateYUVTexture(SDL_SW_YUVTexture * swdata, const SDL_Rect * rect, dst = swdata->planes[0] + rect->y * swdata->pitches[0] + rect->x * 2; - length = rect->w * 2; + length = 4 * ((rect->w + 1) / 2); for (row = 0; row < rect->h; ++row) { SDL_memcpy(dst, src, length); src += pitch; @@ -1195,6 +1266,42 @@ SDL_SW_UpdateYUVTexture(SDL_SW_YUVTexture * swdata, const SDL_Rect * rect, } } break; + case SDL_PIXELFORMAT_NV12: + case SDL_PIXELFORMAT_NV21: + { + if (rect->x == 0 && rect->y == 0 && rect->w == swdata->w && rect->h == swdata->h) { + SDL_memcpy(swdata->pixels, pixels, + (swdata->h * swdata->w) + 2* ((swdata->h + 1) /2) * ((swdata->w + 1) / 2)); + } else { + + Uint8 *src, *dst; + int row; + size_t length; + + /* Copy the Y plane */ + src = (Uint8 *) pixels; + dst = swdata->pixels + rect->y * swdata->w + rect->x; + length = rect->w; + for (row = 0; row < rect->h; ++row) { + SDL_memcpy(dst, src, length); + src += pitch; + dst += swdata->w; + } + + /* Copy the next plane */ + src = (Uint8 *) pixels + rect->h * pitch; + dst = swdata->pixels + swdata->h * swdata->w; + dst += 2 * ((rect->y + 1)/2) * ((swdata->w + 1) / 2) + 2 * (rect->x/2); + length = 2 * ((rect->w + 1) / 2); + for (row = 0; row < (rect->h + 1)/2; ++row) { + SDL_memcpy(dst, src, length); + src += 2 * ((pitch + 1)/2); + dst += 2 * ((swdata->w + 1)/2); + } + } + } + break; + } return 0; } @@ -1226,14 +1333,14 @@ SDL_SW_UpdateYUVTexturePlanar(SDL_SW_YUVTexture * swdata, const SDL_Rect * rect, dst = swdata->pixels + swdata->h * swdata->w; } else { dst = swdata->pixels + swdata->h * swdata->w + - (swdata->h * swdata->w) / 4; + ((swdata->h + 1) / 2) * ((swdata->w + 1) / 2); } - dst += rect->y/2 * swdata->w/2 + rect->x/2; - length = rect->w / 2; - for (row = 0; row < rect->h/2; ++row) { + dst += rect->y/2 * ((swdata->w + 1)/2) + rect->x/2; + length = (rect->w + 1) / 2; + for (row = 0; row < (rect->h + 1)/2; ++row) { SDL_memcpy(dst, src, length); src += Upitch; - dst += swdata->w/2; + dst += (swdata->w + 1)/2; } /* Copy the V plane */ @@ -1242,14 +1349,14 @@ SDL_SW_UpdateYUVTexturePlanar(SDL_SW_YUVTexture * swdata, const SDL_Rect * rect, dst = swdata->pixels + swdata->h * swdata->w; } else { dst = swdata->pixels + swdata->h * swdata->w + - (swdata->h * swdata->w) / 4; + ((swdata->h + 1) / 2) * ((swdata->w + 1) / 2); } - dst += rect->y/2 * swdata->w/2 + rect->x/2; - length = rect->w / 2; - for (row = 0; row < rect->h/2; ++row) { + dst += rect->y/2 * ((swdata->w + 1)/2) + rect->x/2; + length = (rect->w + 1) / 2; + for (row = 0; row < (rect->h + 1)/2; ++row) { SDL_memcpy(dst, src, length); src += Vpitch; - dst += swdata->w/2; + dst += (swdata->w + 1)/2; } return 0; } @@ -1261,11 +1368,13 @@ SDL_SW_LockYUVTexture(SDL_SW_YUVTexture * swdata, const SDL_Rect * rect, switch (swdata->format) { case SDL_PIXELFORMAT_YV12: case SDL_PIXELFORMAT_IYUV: + case SDL_PIXELFORMAT_NV12: + case SDL_PIXELFORMAT_NV21: if (rect && (rect->x != 0 || rect->y != 0 || rect->w != swdata->w || rect->h != swdata->h)) { return SDL_SetError - ("YV12 and IYUV textures only support full surface locks"); + ("YV12, IYUV, NV12, NV21 textures only support full surface locks"); } break; } @@ -1383,6 +1492,12 @@ SDL_SW_CopyYUVToRGB(SDL_SW_YUVTexture * swdata, const SDL_Rect * srcrect, Cr = lum + 1; Cb = lum + 3; break; + case SDL_PIXELFORMAT_NV12: + case SDL_PIXELFORMAT_NV21: + return SDL_ConvertPixels(swdata->w, swdata->h, + swdata->format, swdata->planes[0], swdata->pitches[0], + target_format, pixels, pitch); + break; default: return SDL_SetError("Unsupported YUV format in copy"); } diff --git a/src/render/opengl/SDL_render_gl.c b/src/render/opengl/SDL_render_gl.c index 305a744a06..a950d8b815 100644 --- a/src/render/opengl/SDL_render_gl.c +++ b/src/render/opengl/SDL_render_gl.c @@ -752,12 +752,12 @@ GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) if (texture->format == SDL_PIXELFORMAT_YV12 || texture->format == SDL_PIXELFORMAT_IYUV) { /* Need to add size for the U and V planes */ - size += (2 * (texture->h * data->pitch) / 4); + size += 2 * ((texture->h + 1) / 2) * ((data->pitch + 1) / 2); } if (texture->format == SDL_PIXELFORMAT_NV12 || texture->format == SDL_PIXELFORMAT_NV21) { /* Need to add size for the U/V plane */ - size += ((texture->h * data->pitch) / 2); + size += 2 * ((texture->h + 1) / 2) * ((data->pitch + 1) / 2); } data->pixels = SDL_calloc(1, size); if (!data->pixels) { @@ -875,8 +875,8 @@ GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) GL_CLAMP_TO_EDGE); renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - renderdata->glTexImage2D(data->type, 0, internalFormat, texture_w/2, - texture_h/2, 0, format, type, NULL); + renderdata->glTexImage2D(data->type, 0, internalFormat, (texture_w+1)/2, + (texture_h+1)/2, 0, format, type, NULL); renderdata->glBindTexture(data->type, data->vtexture); renderdata->glTexParameteri(data->type, GL_TEXTURE_MIN_FILTER, @@ -887,8 +887,8 @@ GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) GL_CLAMP_TO_EDGE); renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - renderdata->glTexImage2D(data->type, 0, internalFormat, texture_w/2, - texture_h/2, 0, format, type, NULL); + renderdata->glTexImage2D(data->type, 0, internalFormat, (texture_w+1)/2, + (texture_h+1)/2, 0, format, type, NULL); renderdata->glDisable(data->type); } @@ -909,8 +909,8 @@ GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) GL_CLAMP_TO_EDGE); renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - renderdata->glTexImage2D(data->type, 0, GL_LUMINANCE_ALPHA, texture_w/2, - texture_h/2, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, NULL); + renderdata->glTexImage2D(data->type, 0, GL_LUMINANCE_ALPHA, (texture_w+1)/2, + (texture_h+1)/2, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, NULL); renderdata->glDisable(data->type); } @@ -937,7 +937,7 @@ GL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, rect->h, data->format, data->formattype, pixels); if (data->yuv) { - renderdata->glPixelStorei(GL_UNPACK_ROW_LENGTH, (pitch / 2)); + renderdata->glPixelStorei(GL_UNPACK_ROW_LENGTH, ((pitch + 1) / 2)); /* Skip to the correct offset into the next texture */ pixels = (const void*)((const Uint8*)pixels + rect->h * pitch); @@ -947,29 +947,29 @@ GL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, renderdata->glBindTexture(data->type, data->utexture); } renderdata->glTexSubImage2D(data->type, 0, rect->x/2, rect->y/2, - rect->w/2, rect->h/2, + (rect->w+1)/2, (rect->h+1)/2, data->format, data->formattype, pixels); /* Skip to the correct offset into the next texture */ - pixels = (const void*)((const Uint8*)pixels + (rect->h * pitch)/4); + pixels = (const void*)((const Uint8*)pixels + ((rect->h + 1) / 2) * ((pitch + 1) / 2)); if (texture->format == SDL_PIXELFORMAT_YV12) { renderdata->glBindTexture(data->type, data->utexture); } else { renderdata->glBindTexture(data->type, data->vtexture); } renderdata->glTexSubImage2D(data->type, 0, rect->x/2, rect->y/2, - rect->w/2, rect->h/2, + (rect->w+1)/2, (rect->h+1)/2, data->format, data->formattype, pixels); } if (data->nv12) { - renderdata->glPixelStorei(GL_UNPACK_ROW_LENGTH, (pitch / 2)); + renderdata->glPixelStorei(GL_UNPACK_ROW_LENGTH, ((pitch + 1) / 2)); /* Skip to the correct offset into the next texture */ pixels = (const void*)((const Uint8*)pixels + rect->h * pitch); renderdata->glBindTexture(data->type, data->utexture); renderdata->glTexSubImage2D(data->type, 0, rect->x/2, rect->y/2, - rect->w/2, rect->h/2, + (rect->w + 1)/2, (rect->h + 1)/2, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, pixels); } renderdata->glDisable(data->type); @@ -1000,13 +1000,13 @@ GL_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture, renderdata->glPixelStorei(GL_UNPACK_ROW_LENGTH, Upitch); renderdata->glBindTexture(data->type, data->utexture); renderdata->glTexSubImage2D(data->type, 0, rect->x/2, rect->y/2, - rect->w/2, rect->h/2, + (rect->w + 1)/2, (rect->h + 1)/2, data->format, data->formattype, Uplane); renderdata->glPixelStorei(GL_UNPACK_ROW_LENGTH, Vpitch); renderdata->glBindTexture(data->type, data->vtexture); renderdata->glTexSubImage2D(data->type, 0, rect->x/2, rect->y/2, - rect->w/2, rect->h/2, + (rect->w + 1)/2, (rect->h + 1)/2, data->format, data->formattype, Vplane); renderdata->glDisable(data->type); diff --git a/src/render/opengles2/SDL_render_gles2.c b/src/render/opengles2/SDL_render_gles2.c index 0e87f2aa2f..d5d42c3435 100644 --- a/src/render/opengles2/SDL_render_gles2.c +++ b/src/render/opengles2/SDL_render_gles2.c @@ -619,11 +619,11 @@ GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture) size = texture->h * data->pitch; if (data->yuv) { /* Need to add size for the U and V planes */ - size += (2 * (texture->h * data->pitch) / 4); + size += 2 * ((texture->h + 1) / 2) * ((data->pitch + 1) / 2); } if (data->nv12) { /* Need to add size for the U/V plane */ - size += ((texture->h * data->pitch) / 2); + size += 2 * ((texture->h + 1) / 2) * ((data->pitch + 1) / 2); } data->pixel_data = SDL_calloc(1, size); if (!data->pixel_data) { @@ -646,7 +646,7 @@ GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture) renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_MAG_FILTER, scaleMode); renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - renderdata->glTexImage2D(data->texture_type, 0, format, texture->w / 2, texture->h / 2, 0, format, type, NULL); + renderdata->glTexImage2D(data->texture_type, 0, format, (texture->w + 1) / 2, (texture->h + 1) / 2, 0, format, type, NULL); renderdata->glGenTextures(1, &data->texture_u); if (GL_CheckError("glGenTexures()", renderer) < 0) { @@ -658,7 +658,7 @@ GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture) renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_MAG_FILTER, scaleMode); renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - renderdata->glTexImage2D(data->texture_type, 0, format, texture->w / 2, texture->h / 2, 0, format, type, NULL); + renderdata->glTexImage2D(data->texture_type, 0, format, (texture->w + 1) / 2, (texture->h + 1) / 2, 0, format, type, NULL); if (GL_CheckError("glTexImage2D()", renderer) < 0) { return -1; } @@ -675,7 +675,7 @@ GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture) renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_MAG_FILTER, scaleMode); renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - renderdata->glTexImage2D(data->texture_type, 0, GL_LUMINANCE_ALPHA, texture->w / 2, texture->h / 2, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, NULL); + renderdata->glTexImage2D(data->texture_type, 0, GL_LUMINANCE_ALPHA, (texture->w + 1) / 2, (texture->h + 1) / 2, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, NULL); if (GL_CheckError("glTexImage2D()", renderer) < 0) { return -1; } @@ -775,14 +775,15 @@ GLES2_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect GLES2_TexSubImage2D(data, tdata->texture_type, rect->x / 2, rect->y / 2, - rect->w / 2, - rect->h / 2, + (rect->w + 1) / 2, + (rect->h + 1) / 2, tdata->pixel_format, tdata->pixel_type, - pixels, pitch / 2, 1); + pixels, (pitch + 1) / 2, 1); + /* Skip to the correct offset into the next texture */ - pixels = (const void*)((const Uint8*)pixels + (rect->h * pitch)/4); + pixels = (const void*)((const Uint8*)pixels + ((rect->h + 1) / 2) * ((pitch + 1)/2)); if (texture->format == SDL_PIXELFORMAT_YV12) { data->glBindTexture(tdata->texture_type, tdata->texture_u); } else { @@ -791,11 +792,11 @@ GLES2_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect GLES2_TexSubImage2D(data, tdata->texture_type, rect->x / 2, rect->y / 2, - rect->w / 2, - rect->h / 2, + (rect->w + 1) / 2, + (rect->h + 1) / 2, tdata->pixel_format, tdata->pixel_type, - pixels, pitch / 2, 1); + pixels, (pitch + 1) / 2, 1); } if (tdata->nv12) { @@ -805,11 +806,11 @@ GLES2_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect GLES2_TexSubImage2D(data, tdata->texture_type, rect->x / 2, rect->y / 2, - rect->w / 2, - rect->h / 2, + (rect->w + 1) / 2, + (rect->h + 1) / 2, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, - pixels, pitch, 2); + pixels, 2 * ((pitch + 1) / 2), 2); } return GL_CheckError("glTexSubImage2D()", renderer); @@ -836,8 +837,8 @@ GLES2_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture, GLES2_TexSubImage2D(data, tdata->texture_type, rect->x / 2, rect->y / 2, - rect->w / 2, - rect->h / 2, + (rect->w + 1) / 2, + (rect->h + 1) / 2, tdata->pixel_format, tdata->pixel_type, Vplane, Vpitch, 1); @@ -846,8 +847,8 @@ GLES2_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture, GLES2_TexSubImage2D(data, tdata->texture_type, rect->x / 2, rect->y / 2, - rect->w / 2, - rect->h / 2, + (rect->w + 1) / 2, + (rect->h + 1) / 2, tdata->pixel_format, tdata->pixel_type, Uplane, Upitch, 1); diff --git a/src/video/SDL_surface.c b/src/video/SDL_surface.c index 721c477402..21fe1c010b 100644 --- a/src/video/SDL_surface.c +++ b/src/video/SDL_surface.c @@ -26,6 +26,17 @@ #include "SDL_RLEaccel_c.h" #include "SDL_pixels_c.h" +/* Private routines */ +static int +SDL_ConvertPixels_YUV_to_ARGB8888(int width, int height, + Uint32 src_format, const void *src, + void *dst, int dst_pitch); + +static int +SDL_ConvertPixels_ARGB8888_to_YUV(int width, int height, + const void *src, int src_pitch, + Uint32 dst_format, void *dst); + /* Public routines */ /* @@ -1124,56 +1135,131 @@ int SDL_ConvertPixels(int width, int height, /* Fast path for same format copy */ if (src_format == dst_format) { - int bpp, i; + int i; if (SDL_ISPIXELFORMAT_FOURCC(src_format)) { switch (src_format) { case SDL_PIXELFORMAT_YUY2: case SDL_PIXELFORMAT_UYVY: case SDL_PIXELFORMAT_YVYU: - bpp = 2; + /* Packed planes */ + width = 4 * ((width + 1) / 2); + for (i = height; i--;) { + SDL_memcpy(dst, src, width); + src = (const Uint8*)src + src_pitch; + dst = (Uint8*)dst + dst_pitch; + } break; case SDL_PIXELFORMAT_YV12: case SDL_PIXELFORMAT_IYUV: case SDL_PIXELFORMAT_NV12: case SDL_PIXELFORMAT_NV21: - bpp = 1; + { + /* Y plane */ + for (i = height; i--;) { + SDL_memcpy(dst, src, width); + src = (const Uint8*)src + src_pitch; + dst = (Uint8*)dst + dst_pitch; + } + + /* not sure the pitch is relevant here. + this also works to add the size of two chroma planes */ +#if 0 + SDL_memcpy(dst, src, 2 * ((width + 1)/2) * ((height+1)/2)); +#else + + if (src_format == SDL_PIXELFORMAT_YV12 || src_format == SDL_PIXELFORMAT_IYUV) { + /* U and V planes are a quarter the size of the Y plane */ + width = (width + 1) / 2; + height = (height + 1) / 2; + src_pitch = (src_pitch + 1) / 2; + dst_pitch = (dst_pitch + 1) / 2; + for (i = height * 2; i--;) { + SDL_memcpy(dst, src, width); + src = (Uint8*)src + src_pitch; + dst = (Uint8*)dst + dst_pitch; + } + } else if (src_format == SDL_PIXELFORMAT_NV12 || src_format == SDL_PIXELFORMAT_NV21) { + /* U/V plane is half the height of the Y plane */ + height = (height + 1) / 2; + width = (width + 1) / 2; + src_pitch = (src_pitch + 1) / 2; + dst_pitch = (dst_pitch + 1) / 2; + for (i = height; i--;) { + SDL_memcpy(dst, src, 2 * width); + src = (Uint8*)src + 2 * src_pitch; + dst = (Uint8*)dst + 2 * dst_pitch; + } + } +#endif + } break; default: return SDL_SetError("Unknown FOURCC pixel format"); } } else { - bpp = SDL_BYTESPERPIXEL(src_format); + const int bpp = SDL_BYTESPERPIXEL(src_format); + width *= bpp; + for (i = height; i--;) { + SDL_memcpy(dst, src, width); + src = (const Uint8*)src + src_pitch; + dst = (Uint8*)dst + dst_pitch; + } } - width *= bpp; + return 0; + } - for (i = height; i--;) { - SDL_memcpy(dst, src, width); - src = (Uint8*)src + src_pitch; - dst = (Uint8*)dst + dst_pitch; + /* FOURCC to Any */ + if (SDL_ISPIXELFORMAT_FOURCC(src_format)) { + /* FOURCC to ARGB8888 */ + if (dst_format == SDL_PIXELFORMAT_ARGB8888) { + SDL_ConvertPixels_YUV_to_ARGB8888(width, height, src_format, src, dst, dst_pitch); + return 0; } + else /* FOURCC to not(ARGB8888) : need an intermediate conversion */ + { + int ret; + void *tmp = SDL_malloc(width * height * 4); + if (tmp == NULL) { + return -1; + } - if (src_format == SDL_PIXELFORMAT_YV12 || src_format == SDL_PIXELFORMAT_IYUV) { - /* U and V planes are a quarter the size of the Y plane */ - width /= 2; - height /= 2; - src_pitch /= 2; - dst_pitch /= 2; - for (i = height * 2; i--;) { - SDL_memcpy(dst, src, width); - src = (Uint8*)src + src_pitch; - dst = (Uint8*)dst + dst_pitch; + /* convert src/FOURCC to tmp/ARGB8888 */ + SDL_ConvertPixels_YUV_to_ARGB8888(width, height, src_format, src, tmp, width * 4); + + /* convert tmp/ARGB8888 to dst/dst_format */ + ret = SDL_ConvertPixels(width, height, SDL_PIXELFORMAT_ARGB8888, tmp, width * 4, dst_format, dst, dst_pitch); + SDL_free(tmp); + return ret; + } + } + + /* Any to FOURCC */ + if (SDL_ISPIXELFORMAT_FOURCC(dst_format)) { + /* ARGB8888 to FOURCC */ + if (src_format == SDL_PIXELFORMAT_ARGB8888) { + SDL_ConvertPixels_ARGB8888_to_YUV(width, height, src, src_pitch, dst_format, dst); + return 0; + } + else /* not(ARGB8888) to FOURCC : need an intermediate conversion */ + { + int ret; + void *tmp = SDL_malloc(width * height * 4); + if (tmp == NULL) { + return -1; } - } else if (src_format == SDL_PIXELFORMAT_NV12 || src_format == SDL_PIXELFORMAT_NV21) { - /* U/V plane is half the height of the Y plane */ - height /= 2; - for (i = height; i--;) { - SDL_memcpy(dst, src, width); - src = (Uint8*)src + src_pitch; - dst = (Uint8*)dst + dst_pitch; + /* convert src/src_format to tmp/ARGB8888 */ + ret = SDL_ConvertPixels(width, height, src_format, src, src_pitch, SDL_PIXELFORMAT_ARGB8888, tmp, width * 4); + if (ret == -1) { + SDL_free(tmp); + return ret; } + /* convert tmp/ARGB8888 to dst/FOURCC */ + SDL_ConvertPixels_ARGB8888_to_YUV(width, height, tmp, width * 4, dst_format, dst); + + SDL_free(tmp); + return 0; } - return 0; } if (!SDL_CreateSurfaceOnStack(width, height, src_format, nonconst_src, @@ -1231,4 +1317,472 @@ SDL_FreeSurface(SDL_Surface * surface) SDL_free(surface); } + +/* YUV-RGB conversion */ +#define CLAMP(val) ((val) > 0 ? ((val) < 255 ? (val) : 255) : 0) + +#define MAKE_Y(r, g, b) ((( 66 * (r) + 129 * (g) + 25 * (b) + 128) >> 8) + 16) +#define MAKE_U(r, g, b) ((( -38 * (r) - 74 * (g) + 112 * (b) + 128) >> 8) + 128) +#define MAKE_V(r, g, b) ((( 112 * (r) - 94 * (g) - 18 * (b) + 128) >> 8) + 128) + + +#define MAKE_R(y, u, v) CLAMP(( 298 * ((y) - 16) + 409 * ((v) - 128) + 128) >> 8) +#define MAKE_G(y, u, v) CLAMP(( 298 * ((y) - 16) - 100 * ((u) - 128) - 208 * ((v) - 128) + 128) >> 8) +#define MAKE_B(y, u, v) CLAMP(( 298 * ((y) - 16) + 516 * ((u) - 128) + 128) >> 8) + +static int +SDL_ConvertPixels_YUV_to_ARGB8888(int width, int height, + Uint32 src_format, const void *src, + void *dst, int dst_pitch) +{ + const int sz_plane = width * height; + const int sz_plane_chroma = ((width + 1) / 2) * ((height + 1) / 2); + const int width_remainder = (width & 0x1); + const int width_half = width / 2; + const int curr_row_padding = dst_pitch - 4 * width; + int i, j; + Uint8 *curr_row = (Uint8*)dst; + + // SDL_Log("SDL_ConvertPixels_YUV_to_ARGB8888 (from %s)", SDL_GetPixelFormatName(src_format)); + +#define WRITE_RGB_PIXEL(y, u, v) \ + *((Uint32*)curr_row) = \ + (MAKE_B((y), (u), (v)) \ + | (MAKE_G((y), (u), (v)) << 8) \ + | (MAKE_R((y), (u), (v)) << 16) \ + | 0xff000000); \ + curr_row += 4; \ + + switch (src_format) + { + case SDL_PIXELFORMAT_YV12: + case SDL_PIXELFORMAT_IYUV: + case SDL_PIXELFORMAT_NV12: + case SDL_PIXELFORMAT_NV21: + { + const Uint8 *plane_y = (const Uint8*)src; + + if (src_format == SDL_PIXELFORMAT_YV12 || src_format == SDL_PIXELFORMAT_IYUV) + { + const Uint8 *plane_u = (src_format == SDL_PIXELFORMAT_YV12 ? plane_y + sz_plane + sz_plane_chroma : plane_y + sz_plane); + const Uint8 *plane_v = (src_format == SDL_PIXELFORMAT_YV12 ? plane_y + sz_plane : plane_y + sz_plane + sz_plane_chroma); + + for (j = 0; j < height; j++) { + for (i = 0; i < width_half; i++) { + const Uint8 u = *plane_u++; + const Uint8 v = *plane_v++; + const Uint8 y = *plane_y++; + const Uint8 y1 = *plane_y++; + WRITE_RGB_PIXEL(y, u, v); + WRITE_RGB_PIXEL(y1, u, v); + } + if (width_remainder) { + const Uint8 u = *plane_u++; + const Uint8 v = *plane_v++; + const Uint8 y = *plane_y++; + WRITE_RGB_PIXEL(y, u, v); + } + /* Re-use the same line of chroma planes */ + if ((j & 0x1) == 0x0) { + plane_u -= width_half + width_remainder; + plane_v -= width_half + width_remainder; + } + curr_row += curr_row_padding; + } + } + else if (src_format == SDL_PIXELFORMAT_NV12) + { + const Uint8 *plane_interleaved_uv = plane_y + sz_plane; + for (j = 0; j < height; j++) { + for (i = 0; i < width_half; i++) { + const Uint8 y = *plane_y++; + const Uint8 y1 = *plane_y++; + const Uint8 u = *plane_interleaved_uv++; + const Uint8 v = *plane_interleaved_uv++; + WRITE_RGB_PIXEL(y, u, v); + WRITE_RGB_PIXEL(y1, u, v); + } + if (width_remainder) { + const Uint8 y = *plane_y++; + const Uint8 u = *plane_interleaved_uv++; + const Uint8 v = *plane_interleaved_uv++; + WRITE_RGB_PIXEL(y, u, v); + } + /* Re-use the same line of chroma planes */ + if ((j & 0x1) == 0x0) { + plane_interleaved_uv -= 2 * (width_half + width_remainder); + } + curr_row += curr_row_padding; + } + } + else /* src_format == SDL_PIXELFORMAT_NV21 */ + { + const Uint8 *plane_interleaved_uv = plane_y + sz_plane; + for (j = 0; j < height; j++) { + for (i = 0; i < width_half; i++) { + const Uint8 y = *plane_y++; + const Uint8 y1 = *plane_y++; + const Uint8 v = *plane_interleaved_uv++; + const Uint8 u = *plane_interleaved_uv++; + WRITE_RGB_PIXEL(y, u, v); + WRITE_RGB_PIXEL(y1, u, v); + } + if (width_remainder) { + const Uint8 y = *plane_y++; + const Uint8 v = *plane_interleaved_uv++; + const Uint8 u = *plane_interleaved_uv++; + WRITE_RGB_PIXEL(y, u, v); + } + /* Re-use the same line of chroma planes */ + if ((j & 0x1) == 0x0) { + plane_interleaved_uv -= 2 * (width_half + width_remainder); + } + curr_row += curr_row_padding; + } + } + } + break; + + case SDL_PIXELFORMAT_YUY2: + case SDL_PIXELFORMAT_UYVY: + case SDL_PIXELFORMAT_YVYU: + { + const Uint8 *plane = (const Uint8 *)src; + +#define READ_PACKED_YUV(var1, var2, var3, var4) \ + const Uint8 var1 = plane[0]; \ + const Uint8 var2 = plane[1]; \ + const Uint8 var3 = plane[2]; \ + const Uint8 var4 = plane[3]; \ + plane += 4; \ + + if (src_format == SDL_PIXELFORMAT_YUY2) /* Y U Y1 V */ + { + for (j = 0; j < height; j++) { + for (i = 0; i < width_half; i++) { + READ_PACKED_YUV(y, u, y1, v); + WRITE_RGB_PIXEL(y, u, v); + WRITE_RGB_PIXEL(y1, u, v); + } + if (width_remainder) { + READ_PACKED_YUV(y, u, y1, v); /* y1 unused */ + WRITE_RGB_PIXEL(y, u, v); + } + curr_row += curr_row_padding; + } + } + else if (src_format == SDL_PIXELFORMAT_UYVY) /* U Y V Y1 */ + { + for (j = 0; j < height; j++) { + for (i = 0; i < width_half; i++) { + READ_PACKED_YUV(u, y, v, y1); + WRITE_RGB_PIXEL(y, u, v); + WRITE_RGB_PIXEL(y1, u, v); + } + if (width_remainder) { + READ_PACKED_YUV(u, y, v, y1); /* y1 unused */ + WRITE_RGB_PIXEL(y, u, v); + } + curr_row += curr_row_padding; + } + } + else if (src_format == SDL_PIXELFORMAT_YVYU) /* Y V Y1 U */ + { + for (j = 0; j < height; j++) { + for (i = 0; i < width_half; i++) { + READ_PACKED_YUV(y, v, y1, u); + WRITE_RGB_PIXEL(y, u, v); + WRITE_RGB_PIXEL(y1, u, v); + } + if (width_remainder) { + READ_PACKED_YUV(y, v, y1, u); /* y1 unused */ + WRITE_RGB_PIXEL(y, u, v); + } + curr_row += curr_row_padding; + } + } +#undef READ_PACKED_YUV + } + break; + } +#undef WRITE_RGB_PIXEL + return 0; +} + +static int +SDL_ConvertPixels_ARGB8888_to_YUV(int width, int height, const void *src, int src_pitch, Uint32 dst_format, void *dst) +{ + const int src_pitch_x_2 = src_pitch * 2; + const int sz_plane = width * height; + const int sz_plane_chroma = ((width + 1) / 2) * ((height + 1) / 2); + const int height_half = height / 2; + const int height_remainder = (height & 0x1); + const int width_half = width / 2; + const int width_remainder = (width & 0x1); + int i, j; + + // SDL_Log("SDL_ConvertPixels_ARGB8888_to_YUV (to %s)", SDL_GetPixelFormatName(dst_format)); + + switch (dst_format) + { + case SDL_PIXELFORMAT_YV12: + case SDL_PIXELFORMAT_IYUV: + case SDL_PIXELFORMAT_NV12: + case SDL_PIXELFORMAT_NV21: + { + const Uint8 *curr_row, *next_row; + + Uint8 *plane_y = (Uint8*) dst; + Uint8 *plane_u = (dst_format == SDL_PIXELFORMAT_YV12 ? plane_y + sz_plane + sz_plane_chroma : plane_y + sz_plane); + Uint8 *plane_v = (dst_format == SDL_PIXELFORMAT_YV12 ? plane_y + sz_plane : plane_y + sz_plane + sz_plane_chroma); + Uint8 *plane_interleaved_uv = plane_y + sz_plane; + + curr_row = (const Uint8*)src; + + /* Write Y plane */ + for (j = 0; j < height; j++) { + for (i = 0; i < width; i++) { + const Uint8 b = curr_row[4 * i + 0]; + const Uint8 g = curr_row[4 * i + 1]; + const Uint8 r = curr_row[4 * i + 2]; + *plane_y++ = MAKE_Y(r, g, b); + } + curr_row += src_pitch; + } + + curr_row = (const Uint8*)src; + next_row = (const Uint8*)src; + next_row += src_pitch; + +#if 1 +/* slightly faster */ +#define READ_2x2_PIXELS \ + const Uint32 p1 = ((Uint32 *)curr_row)[2 * i]; \ + const Uint32 p2 = ((Uint32 *)curr_row)[2 * i + 1]; \ + const Uint32 p3 = ((Uint32 *)next_row)[2 * i]; \ + const Uint32 p4 = ((Uint32 *)next_row)[2 * i + 1]; \ + const Uint32 b = ((p1 & 0x000000ff) + (p2 & 0x000000ff) + (p3 & 0x000000ff) + (p4 & 0x000000ff)) >> 2; \ + const Uint32 g = ((p1 & 0x0000ff00) + (p2 & 0x0000ff00) + (p3 & 0x0000ff00) + (p4 & 0x0000ff00)) >> 10; \ + const Uint32 r = ((p1 & 0x00ff0000) + (p2 & 0x00ff0000) + (p3 & 0x00ff0000) + (p4 & 0x00ff0000)) >> 18; \ + +#else + +#define READ_2x2_PIXELS \ + const Uint8 b = (curr_row[8 * i + 0] + curr_row[8 * i + 4] \ + + next_row[8 * i + 0] + next_row[8 * i + 4] ) >> 2; \ + const Uint8 g = (curr_row[8 * i + 1] + curr_row[8 * i + 5] \ + + next_row[8 * i + 1] + next_row[8 * i + 5] ) >> 2; \ + const Uint8 r = (curr_row[8 * i + 2] + curr_row[8 * i + 6] \ + + next_row[8 * i + 2] + next_row[8 * i + 6] ) >> 2; \ + +#endif + +#define READ_2x1_PIXELS \ + const Uint8 b = (curr_row[8 * i + 0] + next_row[8 * i + 0]) >> 1; \ + const Uint8 g = (curr_row[8 * i + 1] + next_row[8 * i + 1]) >> 1; \ + const Uint8 r = (curr_row[8 * i + 2] + next_row[8 * i + 2]) >> 1; \ + +#define READ_1x2_PIXELS \ + const Uint8 b = (curr_row[8 * i + 0] + curr_row[8 * i + 4]) >> 1; \ + const Uint8 g = (curr_row[8 * i + 1] + curr_row[8 * i + 5]) >> 1; \ + const Uint8 r = (curr_row[8 * i + 2] + curr_row[8 * i + 6]) >> 1; \ + +#define READ_1x1_PIXEL \ + const Uint8 b = curr_row[8 * i + 0]; \ + const Uint8 g = curr_row[8 * i + 1]; \ + const Uint8 r = curr_row[8 * i + 2]; \ + + if (dst_format == SDL_PIXELFORMAT_YV12 || dst_format == SDL_PIXELFORMAT_IYUV) + { + /* Write UV planes, not interleaved */ + for (j = 0; j < height_half; j++) { + for (i = 0; i < width_half; i++) { + READ_2x2_PIXELS; + *plane_u++ = MAKE_U(r, g, b); + *plane_v++ = MAKE_V(r, g, b); + } + if (width_remainder) { + READ_2x1_PIXELS; + *plane_u++ = MAKE_U(r, g, b); + *plane_v++ = MAKE_V(r, g, b); + } + curr_row += src_pitch_x_2; + next_row += src_pitch_x_2; + } + if (height_remainder) { + for (i = 0; i < width_half; i++) { + READ_1x2_PIXELS; + *plane_u++ = MAKE_U(r, g, b); + *plane_v++ = MAKE_V(r, g, b); + } + if (width_remainder) { + READ_1x1_PIXEL; + *plane_u++ = MAKE_U(r, g, b); + *plane_v++ = MAKE_V(r, g, b); + } + } + } + else if (dst_format == SDL_PIXELFORMAT_NV12) + { + for (j = 0; j < height_half; j++) { + for (i = 0; i < width_half; i++) { + READ_2x2_PIXELS; + *plane_interleaved_uv++ = MAKE_U(r, g, b); + *plane_interleaved_uv++ = MAKE_V(r, g, b); + } + if (width_remainder) { + READ_2x1_PIXELS; + *plane_interleaved_uv++ = MAKE_U(r, g, b); + *plane_interleaved_uv++ = MAKE_V(r, g, b); + } + curr_row += src_pitch_x_2; + next_row += src_pitch_x_2; + } + if (height_remainder) { + for (i = 0; i < width_half; i++) { + READ_1x2_PIXELS; + *plane_interleaved_uv++ = MAKE_U(r, g, b); + *plane_interleaved_uv++ = MAKE_V(r, g, b); + } + if (width_remainder) { + READ_1x1_PIXEL; + *plane_interleaved_uv++ = MAKE_U(r, g, b); + *plane_interleaved_uv++ = MAKE_V(r, g, b); + } + } + } + else /* dst_format == SDL_PIXELFORMAT_NV21 */ + { + for (j = 0; j < height_half; j++) { + for (i = 0; i < width_half; i++) { + READ_2x2_PIXELS; + *plane_interleaved_uv++ = MAKE_V(r, g, b); + *plane_interleaved_uv++ = MAKE_U(r, g, b); + } + if (width_remainder) { + READ_2x1_PIXELS; + *plane_interleaved_uv++ = MAKE_V(r, g, b); + *plane_interleaved_uv++ = MAKE_U(r, g, b); + } + curr_row += src_pitch_x_2; + next_row += src_pitch_x_2; + } + if (height_remainder) { + for (i = 0; i < width_half; i++) { + READ_1x2_PIXELS; + *plane_interleaved_uv++ = MAKE_V(r, g, b); + *plane_interleaved_uv++ = MAKE_U(r, g, b); + } + if (width_remainder) { + READ_1x1_PIXEL; + *plane_interleaved_uv++ = MAKE_V(r, g, b); + *plane_interleaved_uv++ = MAKE_U(r, g, b); + } + } + } +#undef READ_2x2_PIXELS +#undef READ_2x1_PIXELS +#undef READ_1x2_PIXELS +#undef READ_1x1_PIXEL + } + break; + + case SDL_PIXELFORMAT_YUY2: + case SDL_PIXELFORMAT_UYVY: + case SDL_PIXELFORMAT_YVYU: + { + const Uint8 *curr_row = (const Uint8*) src; + Uint8 *plane = (Uint8*) dst; + +#define READ_TWO_RGB_PIXELS \ + const Uint8 b = curr_row[8 * i + 0]; \ + const Uint8 g = curr_row[8 * i + 1]; \ + const Uint8 r = curr_row[8 * i + 2]; \ + const Uint8 b1 = curr_row[8 * i + 4]; \ + const Uint8 g1 = curr_row[8 * i + 5]; \ + const Uint8 r1 = curr_row[8 * i + 6]; \ + const Uint8 B = (b + b1) >> 1; \ + const Uint8 G = (g + g1) >> 1; \ + const Uint8 R = (r + r1) >> 1; \ + +#define READ_ONE_RGB_PIXEL \ + const Uint8 b = curr_row[8 * i + 0]; \ + const Uint8 g = curr_row[8 * i + 1]; \ + const Uint8 r = curr_row[8 * i + 2]; \ + + /* Write YUV plane, packed */ + if (dst_format == SDL_PIXELFORMAT_YUY2) + { + for (j = 0; j < height; j++) { + for (i = 0; i < width_half; i++) { + READ_TWO_RGB_PIXELS; + /* Y U Y1 V */ + *plane++ = MAKE_Y(r, g, b); + *plane++ = MAKE_U(R, G, B); + *plane++ = MAKE_Y(r1, g1, b1); + *plane++ = MAKE_V(R, G, B); + } + if (width_remainder) { + READ_ONE_RGB_PIXEL; + /* Y U Y V */ + *plane++ = MAKE_Y(r, g, b); + *plane++ = MAKE_U(r, g, b); + *plane++ = MAKE_Y(r, g, b); + *plane++ = MAKE_V(r, g, b); + } + curr_row += src_pitch; + } + } + else if (dst_format == SDL_PIXELFORMAT_UYVY) + { + for (j = 0; j < height; j++) { + for (i = 0; i < width_half; i++) { + READ_TWO_RGB_PIXELS; + /* U Y V Y1 */ + *plane++ = MAKE_U(R, G, B); + *plane++ = MAKE_Y(r, g, b); + *plane++ = MAKE_V(R, G, B); + *plane++ = MAKE_Y(r1, g1, b1); + } + if (width_remainder) { + READ_ONE_RGB_PIXEL; + /* U Y V Y */ + *plane++ = MAKE_U(r, g, b); + *plane++ = MAKE_Y(r, g, b); + *plane++ = MAKE_V(r, g, b); + *plane++ = MAKE_Y(r, g, b); + } + curr_row += src_pitch; + } + } + else if (dst_format == SDL_PIXELFORMAT_YVYU) + { + for (j = 0; j < height; j++) { + for (i = 0; i < width_half; i++) { + READ_TWO_RGB_PIXELS; + /* Y V Y1 U */ + *plane++ = MAKE_Y(r, g, b); + *plane++ = MAKE_V(R, G, B); + *plane++ = MAKE_Y(r1, g1, b1); + *plane++ = MAKE_U(R, G, B); + } + if (width_remainder) { + READ_ONE_RGB_PIXEL; + /* Y V Y U */ + *plane++ = MAKE_Y(r, g, b); + *plane++ = MAKE_V(r, g, b); + *plane++ = MAKE_Y(r, g, b); + *plane++ = MAKE_U(r, g, b); + } + curr_row += src_pitch; + } + } +#undef READ_TWO_RGB_PIXELS +#undef READ_ONE_RGB_PIXEL + } + break; + } + return 0; +} + /* vi: set ts=4 sw=4 expandtab: */ From 54411d356282b4d6bce99f3130e493739b8552fe Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 6 Oct 2017 21:43:59 -0700 Subject: [PATCH 30/95] Fixed restoring window size when coming out of fullscreen desktop mode. Use the style of the window as it will be, not as it currently is at the time of the AdjustWindowRect call. --- src/video/windows/SDL_windowswindow.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/video/windows/SDL_windowswindow.c b/src/video/windows/SDL_windowswindow.c index 336e1e1c88..32849c4422 100644 --- a/src/video/windows/SDL_windowswindow.c +++ b/src/video/windows/SDL_windowswindow.c @@ -595,6 +595,8 @@ WIN_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, style &= ~WS_MAXIMIZE; } } else { + BOOL menu; + /* Restore window-maximization state, as applicable. Special care is taken to *not* do this if and when we're alt-tab'ing away (to some other window; as indicated by @@ -606,7 +608,8 @@ WIN_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, data->windowed_mode_was_maximized = SDL_FALSE; } - WIN_AdjustWindowRect(window, &x, &y, &w, &h, SDL_FALSE); + menu = (style & WS_CHILDWINDOW) ? FALSE : (GetMenu(hwnd) != NULL); + WIN_AdjustWindowRectWithStyle(window, style, menu, &x, &y, &w, &h, SDL_FALSE); } SetWindowLong(hwnd, GWL_STYLE, style); data->expected_resize = SDL_TRUE; From 05f5865c1616f9d86939c112cafe4c20e86be1e9 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sat, 7 Oct 2017 15:26:55 -0700 Subject: [PATCH 31/95] Fixed bug 3857 - SDL_ConvertPixels misses YUV conversions Sylvain There are various YUV-RGB conversion coefficients, according to https://www.fourcc.org/fccyvrgb.php I choose the first (from Video Demystified, with integer multiplication), but the current SDL2 Dither functions use in fact the next one, which follows a specifications called CCIR 601. Here's a patch to use the second ones and with previous warning corrections. There are less multiplications involved because Chroma coefficient is 1. Also, doing float multiplication is as efficient with vectorization. In the end, the YUV decoding is faster: ~165 ms vs my previous 195 ms. Moreover, if SDL2 is compiled with -march=native, then YUV decoding time drops to ~130ms, while older ones remains around ~220 ms. For information, from jpeg-9 source code: jpeg-9/jccolor.c * YCbCr is defined per CCIR 601-1, except that Cb and Cr are * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5. * The conversion equations to be implemented are therefore * Y = 0.29900 * R + 0.58700 * G + 0.11400 * B * Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B + CENTERJSAMPLE * Cr = 0.50000 * R - 0.41869 * G - 0.08131 * B + CENTERJSAMPLE jpeg-9/jdcolor.c * YCbCr is defined per CCIR 601-1, except that Cb and Cr are * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5. * The conversion equations to be implemented are therefore * * R = Y + 1.40200 * Cr * G = Y - 0.34414 * Cb - 0.71414 * Cr * B = Y + 1.77200 * Cb --- src/video/SDL_surface.c | 39 +++++++++++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/src/video/SDL_surface.c b/src/video/SDL_surface.c index 21fe1c010b..2c64291db0 100644 --- a/src/video/SDL_surface.c +++ b/src/video/SDL_surface.c @@ -1176,7 +1176,7 @@ int SDL_ConvertPixels(int width, int height, dst_pitch = (dst_pitch + 1) / 2; for (i = height * 2; i--;) { SDL_memcpy(dst, src, width); - src = (Uint8*)src + src_pitch; + src = (const Uint8*)src + src_pitch; dst = (Uint8*)dst + dst_pitch; } } else if (src_format == SDL_PIXELFORMAT_NV12 || src_format == SDL_PIXELFORMAT_NV21) { @@ -1187,7 +1187,7 @@ int SDL_ConvertPixels(int width, int height, dst_pitch = (dst_pitch + 1) / 2; for (i = height; i--;) { SDL_memcpy(dst, src, 2 * width); - src = (Uint8*)src + 2 * src_pitch; + src = (const Uint8*)src + 2 * src_pitch; dst = (Uint8*)dst + 2 * dst_pitch; } } @@ -1321,15 +1321,31 @@ SDL_FreeSurface(SDL_Surface * surface) /* YUV-RGB conversion */ #define CLAMP(val) ((val) > 0 ? ((val) < 255 ? (val) : 255) : 0) +#if 1 + +/* Coefficients from CCIR 601 */ +#define MAKE_Y(r, g, b) (int)( 0.29900f * (r) + 0.58700f * (g) + 0.11400f * (b)) +#define MAKE_U(r, g, b) (int)(-0.16874f * (r) - 0.33126f * (g) + 0.50000f * (b) + 128) +#define MAKE_V(r, g, b) (int)( 0.50000f * (r) - 0.41869f * (g) - 0.08131f * (b) + 128) + +#define MAKE_R(y, u, v) CLAMP((int)((y) + 1.40200f * ((v) - 128))) +#define MAKE_G(y, u, v) CLAMP((int)((y) - 0.34414f * ((u) - 128) - 0.71414f * ((v) - 128))) +#define MAKE_B(y, u, v) CLAMP((int)((y) + 1.77200f * ((u) - 128) )) + +#else + +/* Coefficients from Video Demystified */ #define MAKE_Y(r, g, b) ((( 66 * (r) + 129 * (g) + 25 * (b) + 128) >> 8) + 16) #define MAKE_U(r, g, b) ((( -38 * (r) - 74 * (g) + 112 * (b) + 128) >> 8) + 128) #define MAKE_V(r, g, b) ((( 112 * (r) - 94 * (g) - 18 * (b) + 128) >> 8) + 128) - #define MAKE_R(y, u, v) CLAMP(( 298 * ((y) - 16) + 409 * ((v) - 128) + 128) >> 8) #define MAKE_G(y, u, v) CLAMP(( 298 * ((y) - 16) - 100 * ((u) - 128) - 208 * ((v) - 128) + 128) >> 8) #define MAKE_B(y, u, v) CLAMP(( 298 * ((y) - 16) + 516 * ((u) - 128) + 128) >> 8) +#endif + + static int SDL_ConvertPixels_YUV_to_ARGB8888(int width, int height, Uint32 src_format, const void *src, @@ -1465,7 +1481,8 @@ SDL_ConvertPixels_YUV_to_ARGB8888(int width, int height, WRITE_RGB_PIXEL(y1, u, v); } if (width_remainder) { - READ_PACKED_YUV(y, u, y1, v); /* y1 unused */ + READ_PACKED_YUV(y, u, y1, v); + (void)y1; /* y1 unused */ WRITE_RGB_PIXEL(y, u, v); } curr_row += curr_row_padding; @@ -1480,7 +1497,8 @@ SDL_ConvertPixels_YUV_to_ARGB8888(int width, int height, WRITE_RGB_PIXEL(y1, u, v); } if (width_remainder) { - READ_PACKED_YUV(u, y, v, y1); /* y1 unused */ + READ_PACKED_YUV(u, y, v, y1); + (void) y1; /* y1 unused */ WRITE_RGB_PIXEL(y, u, v); } curr_row += curr_row_padding; @@ -1495,7 +1513,8 @@ SDL_ConvertPixels_YUV_to_ARGB8888(int width, int height, WRITE_RGB_PIXEL(y1, u, v); } if (width_remainder) { - READ_PACKED_YUV(y, v, y1, u); /* y1 unused */ + READ_PACKED_YUV(y, v, y1, u); + (void) y1; /* y1 unused */ WRITE_RGB_PIXEL(y, u, v); } curr_row += curr_row_padding; @@ -1557,10 +1576,10 @@ SDL_ConvertPixels_ARGB8888_to_YUV(int width, int height, const void *src, int sr #if 1 /* slightly faster */ #define READ_2x2_PIXELS \ - const Uint32 p1 = ((Uint32 *)curr_row)[2 * i]; \ - const Uint32 p2 = ((Uint32 *)curr_row)[2 * i + 1]; \ - const Uint32 p3 = ((Uint32 *)next_row)[2 * i]; \ - const Uint32 p4 = ((Uint32 *)next_row)[2 * i + 1]; \ + const Uint32 p1 = ((const Uint32 *)curr_row)[2 * i]; \ + const Uint32 p2 = ((const Uint32 *)curr_row)[2 * i + 1]; \ + const Uint32 p3 = ((const Uint32 *)next_row)[2 * i]; \ + const Uint32 p4 = ((const Uint32 *)next_row)[2 * i + 1]; \ const Uint32 b = ((p1 & 0x000000ff) + (p2 & 0x000000ff) + (p3 & 0x000000ff) + (p4 & 0x000000ff)) >> 2; \ const Uint32 g = ((p1 & 0x0000ff00) + (p2 & 0x0000ff00) + (p3 & 0x0000ff00) + (p4 & 0x0000ff00)) >> 10; \ const Uint32 r = ((p1 & 0x00ff0000) + (p2 & 0x00ff0000) + (p3 & 0x00ff0000) + (p4 & 0x00ff0000)) >> 18; \ From 54eeab3efae284241ec94e2c18bea9a42edd1fe2 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sun, 8 Oct 2017 10:59:03 -0700 Subject: [PATCH 32/95] Fixed bug 3865 - [PATCH] Support for GreenAsia Inc. PSX to USB converter as SDL_GameController Manuel I would like this small patch merged that adds support for my GreenAsia Inc. PSX to USB converter, so SDL_IsGameController() returns true when using this adaptor. It's interesting because PSX/PS2 controllers connected using this model won't be detected as gamecontrollers otherwise, only as joysticks. --- src/joystick/SDL_gamecontrollerdb.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/joystick/SDL_gamecontrollerdb.h b/src/joystick/SDL_gamecontrollerdb.h index 9583c9321e..951cd0b6f7 100644 --- a/src/joystick/SDL_gamecontrollerdb.h +++ b/src/joystick/SDL_gamecontrollerdb.h @@ -163,6 +163,7 @@ static const char *s_ControllerMappings [] = "030000000d0500000308000010010000,Nostromo n45 Dual Analog Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b12,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b10,x:b2,y:b3,", "05000000362800000100000002010000,OUYA Game Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,", "030000006f0e00006401000001010000,PDP Battlefield One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", + "03000000ff1100004133000010010000,PS2 Controller,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,", "030000004c0500006802000010010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,", "050000004c0500006802000000010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:a12,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:a13,rightx:a2,righty:a3,start:b3,x:b15,y:b12,", "030000004c0500006802000011010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,", From adf8e605d106a4fb8b79dfb192a813619073470f Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Mon, 9 Oct 2017 11:45:15 -0700 Subject: [PATCH 33/95] Fixed crash in SDL_IsGameController() on Windows if called when a controller is being removed --- src/joystick/SDL_gamecontroller.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/joystick/SDL_gamecontroller.c b/src/joystick/SDL_gamecontroller.c index 1483c98a85..0802c88c76 100644 --- a/src/joystick/SDL_gamecontroller.c +++ b/src/joystick/SDL_gamecontroller.c @@ -906,14 +906,20 @@ static ControllerMapping_t *SDL_PrivateGetControllerMappingForNameAndGUID(const static ControllerMapping_t *SDL_PrivateGetControllerMapping(int device_index) { - const char *name = SDL_JoystickNameForIndex(device_index); - SDL_JoystickGUID guid = SDL_JoystickGetDeviceGUID(device_index); - ControllerMapping_t *mapping = SDL_PrivateGetControllerMappingForNameAndGUID(name, guid); + const char *name; + SDL_JoystickGUID guid; + ControllerMapping_t *mapping; + + SDL_LockJoystickList(); + name = SDL_JoystickNameForIndex(device_index); + guid = SDL_JoystickGetDeviceGUID(device_index); + mapping = SDL_PrivateGetControllerMappingForNameAndGUID(name, guid); #if SDL_JOYSTICK_XINPUT if (!mapping && SDL_SYS_IsXInputGamepad_DeviceIndex(device_index)) { mapping = s_pXInputMapping; } #endif + SDL_UnlockJoystickList(); return mapping; } From 770709835d2b689fb7bdca8d659bd9ad39b041bd Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 10 Oct 2017 11:10:15 -0700 Subject: [PATCH 34/95] Exposed the joystick locking functions for multi-threaded access to the joystick API --- include/SDL_joystick.h | 14 ++++++++++ src/dynapi/SDL_dynapi_overrides.h | 2 ++ src/dynapi/SDL_dynapi_procs.h | 2 ++ src/joystick/SDL_gamecontroller.c | 38 +++++++++++++------------- src/joystick/SDL_joystick.c | 44 +++++++++++++++---------------- src/joystick/SDL_joystick_c.h | 4 --- 6 files changed, 59 insertions(+), 45 deletions(-) diff --git a/include/SDL_joystick.h b/include/SDL_joystick.h index 698b09c142..f598dc828d 100644 --- a/include/SDL_joystick.h +++ b/include/SDL_joystick.h @@ -106,6 +106,20 @@ typedef enum } SDL_JoystickPowerLevel; /* Function prototypes */ + +/** + * Locking for multi-threaded access to the joystick API + * + * If you are using the joystick API or handling events from multiple threads + * you should use these locking functions to protect access to the joysticks. + * + * In particular, you are guaranteed that the joystick list won't change, so + * the API functions that take a joystick index will be valid, and joystick + * and game controller events will not be delivered. + */ +extern DECLSPEC void SDLCALL SDL_LockJoysticks(void); +extern DECLSPEC void SDLCALL SDL_UnlockJoysticks(void); + /** * Count the number of joysticks attached to the system right now */ diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h index 95943bc1f6..3ef56d23af 100644 --- a/src/dynapi/SDL_dynapi_overrides.h +++ b/src/dynapi/SDL_dynapi_overrides.h @@ -635,3 +635,5 @@ #define SDL_Vulkan_GetInstanceExtensions SDL_Vulkan_GetInstanceExtensions_REAL #define SDL_Vulkan_CreateSurface SDL_Vulkan_CreateSurface_REAL #define SDL_Vulkan_GetDrawableSize SDL_Vulkan_GetDrawableSize_REAL +#define SDL_LockJoysticks SDL_LockJoysticks_REAL +#define SDL_UnlockJoysticks SDL_UnlockJoysticks_REAL diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h index b7466fdb64..730fbcc327 100644 --- a/src/dynapi/SDL_dynapi_procs.h +++ b/src/dynapi/SDL_dynapi_procs.h @@ -669,3 +669,5 @@ SDL_DYNAPI_PROC(void,SDL_Vulkan_UnloadLibrary,(void),(),) SDL_DYNAPI_PROC(SDL_bool,SDL_Vulkan_GetInstanceExtensions,(SDL_Window *a, unsigned int *b, const char **c),(a,b,c),return) SDL_DYNAPI_PROC(SDL_bool,SDL_Vulkan_CreateSurface,(SDL_Window *a, VkInstance b, VkSurfaceKHR *c),(a,b,c),return) SDL_DYNAPI_PROC(void,SDL_Vulkan_GetDrawableSize,(SDL_Window *a, int *b, int *c),(a,b,c),) +SDL_DYNAPI_PROC(void,SDL_LockJoysticks,(void),(),) +SDL_DYNAPI_PROC(void,SDL_UnlockJoysticks,(void),(),) diff --git a/src/joystick/SDL_gamecontroller.c b/src/joystick/SDL_gamecontroller.c index 0802c88c76..13953de51c 100644 --- a/src/joystick/SDL_gamecontroller.c +++ b/src/joystick/SDL_gamecontroller.c @@ -24,9 +24,9 @@ #include "SDL_events.h" #include "SDL_assert.h" +#include "SDL_hints.h" #include "SDL_sysjoystick.h" #include "SDL_joystick_c.h" -#include "SDL_hints.h" #include "SDL_gamecontrollerdb.h" #if !SDL_EVENTS_DISABLED @@ -910,7 +910,7 @@ static ControllerMapping_t *SDL_PrivateGetControllerMapping(int device_index) SDL_JoystickGUID guid; ControllerMapping_t *mapping; - SDL_LockJoystickList(); + SDL_LockJoysticks(); name = SDL_JoystickNameForIndex(device_index); guid = SDL_JoystickGetDeviceGUID(device_index); mapping = SDL_PrivateGetControllerMappingForNameAndGUID(name, guid); @@ -919,7 +919,7 @@ static ControllerMapping_t *SDL_PrivateGetControllerMapping(int device_index) mapping = s_pXInputMapping; } #endif - SDL_UnlockJoystickList(); + SDL_UnlockJoysticks(); return mapping; } @@ -1349,7 +1349,7 @@ SDL_GameControllerOpen(int device_index) return (NULL); } - SDL_LockJoystickList(); + SDL_LockJoysticks(); gamecontrollerlist = SDL_gamecontrollers; /* If the controller is already open, return it */ @@ -1357,7 +1357,7 @@ SDL_GameControllerOpen(int device_index) if (SDL_SYS_GetInstanceIdOfDeviceIndex(device_index) == gamecontrollerlist->joystick->instance_id) { gamecontroller = gamecontrollerlist; ++gamecontroller->ref_count; - SDL_UnlockJoystickList(); + SDL_UnlockJoysticks(); return (gamecontroller); } gamecontrollerlist = gamecontrollerlist->next; @@ -1367,7 +1367,7 @@ SDL_GameControllerOpen(int device_index) pSupportedController = SDL_PrivateGetControllerMapping(device_index); if (!pSupportedController) { SDL_SetError("Couldn't find mapping for device (%d)", device_index); - SDL_UnlockJoystickList(); + SDL_UnlockJoysticks(); return NULL; } @@ -1375,14 +1375,14 @@ SDL_GameControllerOpen(int device_index) gamecontroller = (SDL_GameController *) SDL_calloc(1, sizeof(*gamecontroller)); if (gamecontroller == NULL) { SDL_OutOfMemory(); - SDL_UnlockJoystickList(); + SDL_UnlockJoysticks(); return NULL; } gamecontroller->joystick = SDL_JoystickOpen(device_index); if (!gamecontroller->joystick) { SDL_free(gamecontroller); - SDL_UnlockJoystickList(); + SDL_UnlockJoysticks(); return NULL; } @@ -1392,7 +1392,7 @@ SDL_GameControllerOpen(int device_index) SDL_OutOfMemory(); SDL_JoystickClose(gamecontroller->joystick); SDL_free(gamecontroller); - SDL_UnlockJoystickList(); + SDL_UnlockJoysticks(); return NULL; } } @@ -1403,7 +1403,7 @@ SDL_GameControllerOpen(int device_index) SDL_JoystickClose(gamecontroller->joystick); SDL_free(gamecontroller->last_match_axis); SDL_free(gamecontroller); - SDL_UnlockJoystickList(); + SDL_UnlockJoysticks(); return NULL; } } @@ -1416,7 +1416,7 @@ SDL_GameControllerOpen(int device_index) gamecontroller->next = SDL_gamecontrollers; SDL_gamecontrollers = gamecontroller; - SDL_UnlockJoystickList(); + SDL_UnlockJoysticks(); return (gamecontroller); } @@ -1589,16 +1589,16 @@ SDL_GameControllerFromInstanceID(SDL_JoystickID joyid) { SDL_GameController *gamecontroller; - SDL_LockJoystickList(); + SDL_LockJoysticks(); gamecontroller = SDL_gamecontrollers; while (gamecontroller) { if (gamecontroller->joystick->instance_id == joyid) { - SDL_UnlockJoystickList(); + SDL_UnlockJoysticks(); return gamecontroller; } gamecontroller = gamecontroller->next; } - SDL_UnlockJoystickList(); + SDL_UnlockJoysticks(); return NULL; } @@ -1674,11 +1674,11 @@ SDL_GameControllerClose(SDL_GameController * gamecontroller) if (!gamecontroller) return; - SDL_LockJoystickList(); + SDL_LockJoysticks(); /* First decrement ref count */ if (--gamecontroller->ref_count > 0) { - SDL_UnlockJoystickList(); + SDL_UnlockJoysticks(); return; } @@ -1705,7 +1705,7 @@ SDL_GameControllerClose(SDL_GameController * gamecontroller) SDL_free(gamecontroller->last_hat_mask); SDL_free(gamecontroller); - SDL_UnlockJoystickList(); + SDL_UnlockJoysticks(); } @@ -1715,12 +1715,12 @@ SDL_GameControllerClose(SDL_GameController * gamecontroller) void SDL_GameControllerQuit(void) { - SDL_LockJoystickList(); + SDL_LockJoysticks(); while (SDL_gamecontrollers) { SDL_gamecontrollers->ref_count = 1; SDL_GameControllerClose(SDL_gamecontrollers); } - SDL_UnlockJoystickList(); + SDL_UnlockJoysticks(); } void diff --git a/src/joystick/SDL_joystick.c b/src/joystick/SDL_joystick.c index 0724db258a..4c4cae7578 100644 --- a/src/joystick/SDL_joystick.c +++ b/src/joystick/SDL_joystick.c @@ -40,7 +40,7 @@ static SDL_bool SDL_updating_joystick = SDL_FALSE; static SDL_mutex *SDL_joystick_lock = NULL; /* This needs to support recursive locks */ void -SDL_LockJoystickList(void) +SDL_LockJoysticks(void) { if (SDL_joystick_lock) { SDL_LockMutex(SDL_joystick_lock); @@ -48,7 +48,7 @@ SDL_LockJoystickList(void) } void -SDL_UnlockJoystickList(void) +SDL_UnlockJoysticks(void) { if (SDL_joystick_lock) { SDL_UnlockMutex(SDL_joystick_lock); @@ -168,7 +168,7 @@ SDL_JoystickOpen(int device_index) return (NULL); } - SDL_LockJoystickList(); + SDL_LockJoysticks(); joysticklist = SDL_joysticks; /* If the joystick is already open, return it @@ -178,7 +178,7 @@ SDL_JoystickOpen(int device_index) if (SDL_JoystickGetDeviceInstanceID(device_index) == joysticklist->instance_id) { joystick = joysticklist; ++joystick->ref_count; - SDL_UnlockJoystickList(); + SDL_UnlockJoysticks(); return (joystick); } joysticklist = joysticklist->next; @@ -188,13 +188,13 @@ SDL_JoystickOpen(int device_index) joystick = (SDL_Joystick *) SDL_calloc(sizeof(*joystick), 1); if (joystick == NULL) { SDL_OutOfMemory(); - SDL_UnlockJoystickList(); + SDL_UnlockJoysticks(); return NULL; } if (SDL_SYS_JoystickOpen(joystick, device_index) < 0) { SDL_free(joystick); - SDL_UnlockJoystickList(); + SDL_UnlockJoysticks(); return NULL; } @@ -222,7 +222,7 @@ SDL_JoystickOpen(int device_index) || ((joystick->nbuttons > 0) && !joystick->buttons)) { SDL_OutOfMemory(); SDL_JoystickClose(joystick); - SDL_UnlockJoystickList(); + SDL_UnlockJoysticks(); return NULL; } joystick->epowerlevel = SDL_JOYSTICK_POWER_UNKNOWN; @@ -244,7 +244,7 @@ SDL_JoystickOpen(int device_index) joystick->next = SDL_joysticks; SDL_joysticks = joystick; - SDL_UnlockJoystickList(); + SDL_UnlockJoysticks(); SDL_SYS_JoystickUpdate(joystick); @@ -460,14 +460,14 @@ SDL_JoystickFromInstanceID(SDL_JoystickID joyid) { SDL_Joystick *joystick; - SDL_LockJoystickList(); + SDL_LockJoysticks(); for (joystick = SDL_joysticks; joystick; joystick = joystick->next) { if (joystick->instance_id == joyid) { - SDL_UnlockJoystickList(); + SDL_UnlockJoysticks(); return joystick; } } - SDL_UnlockJoystickList(); + SDL_UnlockJoysticks(); return NULL; } @@ -497,16 +497,16 @@ SDL_JoystickClose(SDL_Joystick * joystick) return; } - SDL_LockJoystickList(); + SDL_LockJoysticks(); /* First decrement ref count */ if (--joystick->ref_count > 0) { - SDL_UnlockJoystickList(); + SDL_UnlockJoysticks(); return; } if (SDL_updating_joystick) { - SDL_UnlockJoystickList(); + SDL_UnlockJoysticks(); return; } @@ -538,7 +538,7 @@ SDL_JoystickClose(SDL_Joystick * joystick) SDL_free(joystick->buttons); SDL_free(joystick); - SDL_UnlockJoystickList(); + SDL_UnlockJoysticks(); } void @@ -547,7 +547,7 @@ SDL_JoystickQuit(void) /* Make sure we're not getting called in the middle of updating joysticks */ SDL_assert(!SDL_updating_joystick); - SDL_LockJoystickList(); + SDL_LockJoysticks(); /* Stop the event polling */ while (SDL_joysticks) { @@ -558,7 +558,7 @@ SDL_JoystickQuit(void) /* Quit the joystick setup */ SDL_SYS_JoystickQuit(); - SDL_UnlockJoystickList(); + SDL_UnlockJoysticks(); #if !SDL_EVENTS_DISABLED SDL_QuitSubSystem(SDL_INIT_EVENTS); @@ -847,18 +847,18 @@ SDL_JoystickUpdate(void) { SDL_Joystick *joystick; - SDL_LockJoystickList(); + SDL_LockJoysticks(); if (SDL_updating_joystick) { /* The joysticks are already being updated */ - SDL_UnlockJoystickList(); + SDL_UnlockJoysticks(); return; } SDL_updating_joystick = SDL_TRUE; /* Make sure the list is unlocked while dispatching events to prevent application deadlocks */ - SDL_UnlockJoystickList(); + SDL_UnlockJoysticks(); for (joystick = SDL_joysticks; joystick; joystick = joystick->next) { SDL_SYS_JoystickUpdate(joystick); @@ -885,7 +885,7 @@ SDL_JoystickUpdate(void) } } - SDL_LockJoystickList(); + SDL_LockJoysticks(); SDL_updating_joystick = SDL_FALSE; @@ -901,7 +901,7 @@ SDL_JoystickUpdate(void) */ SDL_SYS_JoystickDetect(); - SDL_UnlockJoystickList(); + SDL_UnlockJoysticks(); } int diff --git a/src/joystick/SDL_joystick_c.h b/src/joystick/SDL_joystick_c.h index 5339b83780..85d3920042 100644 --- a/src/joystick/SDL_joystick_c.h +++ b/src/joystick/SDL_joystick_c.h @@ -33,10 +33,6 @@ extern void SDL_GameControllerQuitMappings(void); extern int SDL_GameControllerInit(void); extern void SDL_GameControllerQuit(void); -/* Locking for multi-threaded access to the joystick API */ -extern void SDL_LockJoystickList(void); -extern void SDL_UnlockJoystickList(void); - /* Function to extract information from an SDL joystick GUID */ extern void SDL_GetJoystickGUIDInfo(SDL_JoystickGUID guid, Uint16 *vendor, Uint16 *product, Uint16 *version); From f166f6e72687910f05e11c51906c60ab72ac6865 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 10 Oct 2017 11:56:54 -0400 Subject: [PATCH 35/95] Added SDL_PeekIntoDataQueue(). --- src/SDL_dataqueue.c | 25 +++++++++++++++++++++++++ src/SDL_dataqueue.h | 1 + 2 files changed, 26 insertions(+) diff --git a/src/SDL_dataqueue.c b/src/SDL_dataqueue.c index db1adaad8e..84370fcbcc 100644 --- a/src/SDL_dataqueue.c +++ b/src/SDL_dataqueue.c @@ -225,6 +225,31 @@ SDL_WriteToDataQueue(SDL_DataQueue *queue, const void *_data, const size_t _len) return 0; } +size_t +SDL_PeekIntoDataQueue(SDL_DataQueue *queue, void *_buf, const size_t _len) +{ + size_t len = _len; + Uint8 *buf = (Uint8 *) _buf; + Uint8 *ptr = buf; + SDL_DataQueuePacket *packet; + + if (!queue) { + return 0; + } + + for (packet = queue->head; len && packet; packet = packet->next) { + const size_t avail = packet->datalen - packet->startpos; + const size_t cpy = SDL_min(len, avail); + SDL_assert(queue->queued_bytes >= avail); + + SDL_memcpy(ptr, packet->data + packet->startpos, cpy); + ptr += cpy; + len -= cpy; + } + + return (size_t) (ptr - buf); +} + size_t SDL_ReadFromDataQueue(SDL_DataQueue *queue, void *_buf, const size_t _len) { diff --git a/src/SDL_dataqueue.h b/src/SDL_dataqueue.h index a5e3e1c60e..8f135c0cfc 100644 --- a/src/SDL_dataqueue.h +++ b/src/SDL_dataqueue.h @@ -31,6 +31,7 @@ void SDL_FreeDataQueue(SDL_DataQueue *queue); void SDL_ClearDataQueue(SDL_DataQueue *queue, const size_t slack); int SDL_WriteToDataQueue(SDL_DataQueue *queue, const void *data, const size_t len); size_t SDL_ReadFromDataQueue(SDL_DataQueue *queue, void *buf, const size_t len); +size_t SDL_PeekIntoDataQueue(SDL_DataQueue *queue, void *buf, const size_t len); size_t SDL_CountDataQueue(SDL_DataQueue *queue); /* this sets a section of the data queue aside (possibly allocating memory for it) From 18ed836874df1c5d1808b967d4eedfb5dc657b73 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 10 Oct 2017 16:12:56 -0400 Subject: [PATCH 36/95] audio: reworked audio streams to have right-hand resampling padding available. Fixes Bugzilla #3851. --- src/audio/SDL_audiocvt.c | 214 ++++++++++++++++++++++++--------------- 1 file changed, 135 insertions(+), 79 deletions(-) diff --git a/src/audio/SDL_audiocvt.c b/src/audio/SDL_audiocvt.c index f2d2464817..68e0b4cad0 100644 --- a/src/audio/SDL_audiocvt.c +++ b/src/audio/SDL_audiocvt.c @@ -31,6 +31,8 @@ #include "../SDL_dataqueue.h" #include "SDL_cpuinfo.h" +#define DEBUG_AUDIOSTREAM 0 + #ifdef __SSE3__ #define HAVE_SSE3_INTRINSICS 1 #endif @@ -467,14 +469,20 @@ SDL_FreeResampleFilter(void) static int ResamplerPadding(const int inrate, const int outrate) { - return (inrate > outrate) ? (int) SDL_ceil(((float) (RESAMPLER_SAMPLES_PER_ZERO_CROSSING * inrate) / ((float) outrate))) : RESAMPLER_SAMPLES_PER_ZERO_CROSSING; + if (inrate == outrate) { + return 0; + } else if (inrate > outrate) { + return (int) SDL_ceil(((float) (RESAMPLER_SAMPLES_PER_ZERO_CROSSING * inrate) / ((float) outrate))); + } + return RESAMPLER_SAMPLES_PER_ZERO_CROSSING; } /* lpadding and rpadding are expected to be buffers of (ResamplePadding(inrate, outrate) * chans * sizeof (float)) bytes. */ static int SDL_ResampleAudio(const int chans, const int inrate, const int outrate, - float *lpadding, float *rpadding, const float *inbuf, - const int inbuflen, float *outbuf, const int outbuflen) + const float *lpadding, const float *rpadding, + const float *inbuf, const int inbuflen, + float *outbuf, const int outbuflen) { const float outtimeincr = 1.0f / ((float) outrate); const float ratio = ((float) outrate) / ((float) inrate); @@ -483,7 +491,7 @@ SDL_ResampleAudio(const int chans, const int inrate, const int outrate, const int inframes = inbuflen / framelen; const int wantedoutframes = (int) ((inbuflen / framelen) * ratio); /* outbuflen isn't total to write, it's total available. */ const int maxoutframes = outbuflen / framelen; - const int outframes = (wantedoutframes < maxoutframes) ? wantedoutframes : maxoutframes; + const int outframes = SDL_min(wantedoutframes, maxoutframes); float *dst = outbuf; float outtime = 0.0f; int i, j, chan; @@ -1076,6 +1084,7 @@ struct SDL_AudioStream SDL_AudioCVT cvt_before_resampling; SDL_AudioCVT cvt_after_resampling; SDL_DataQueue *queue; + SDL_bool first_run; Uint8 *work_buffer_base; /* maybe unaligned pointer from SDL_realloc(). */ int work_buffer_len; int src_sample_frame_size; @@ -1089,6 +1098,8 @@ struct SDL_AudioStream double rate_incr; Uint8 pre_resample_channels; int packetlen; + int resampler_padding_samples; + float *resampler_padding; void *resampler_state; SDL_ResampleAudioStreamFunc resampler_func; SDL_ResetAudioStreamResamplerFunc reset_resampler_func; @@ -1129,16 +1140,7 @@ SDL_ResampleAudioStream_SRC(SDL_AudioStream *stream, const void *_inbuf, const i SRC_DATA data; int result; - if (inbuf == ((const float *) outbuf)) { /* libsamplerate can't work in-place. */ - Uint8 *ptr = EnsureStreamBufferSize(stream, inbuflen + outbuflen); - if (ptr == NULL) { - SDL_OutOfMemory(); - return 0; - } - SDL_memcpy(ptr + outbuflen, ptr, inbuflen); - inbuf = (const float *) (ptr + outbuflen); - outbuf = (float *) ptr; - } + SDL_assert(inbuf != ((const float *) outbuf)); /* SDL_AudioStreamPut() shouldn't allow in-place resamples. */ data.data_in = (float *)inbuf; /* Older versions of libsamplerate had a non-const pointer, but didn't write to it */ data.input_frames = inbuflen / framelen; @@ -1213,54 +1215,32 @@ SetupLibSampleRateResampling(SDL_AudioStream *stream) static int SDL_ResampleAudioStream(SDL_AudioStream *stream, const void *_inbuf, const int inbuflen, void *_outbuf, const int outbuflen) { + const Uint8 *inbufend = ((const Uint8 *) _inbuf) + inbuflen; const float *inbuf = (const float *) _inbuf; float *outbuf = (float *) _outbuf; const int chans = (int) stream->pre_resample_channels; const int inrate = stream->src_rate; const int outrate = stream->dst_rate; - const int paddingsamples = ResamplerPadding(inrate, outrate) * chans; + const int paddingsamples = stream->resampler_padding_samples; const int paddingbytes = paddingsamples * sizeof (float); float *lpadding = (float *) stream->resampler_state; - float *rpadding; + const float *rpadding = (const float *) inbufend; /* we set this up so there are valid padding samples at the end of the input buffer. */ int retval; - if (inbuf == ((const float *) outbuf)) { /* !!! FIXME can't work in-place (for now!). */ - Uint8 *ptr = EnsureStreamBufferSize(stream, inbuflen + outbuflen); - if (ptr == NULL) { - SDL_OutOfMemory(); - return 0; - } - SDL_memcpy(ptr + outbuflen, ptr, inbuflen); - inbuf = (const float *) (ptr + outbuflen); - outbuf = (float *) ptr; - } - - /* !!! FIXME: streaming current resamples on Put, because of probably good reasons I can't remember right now, but if we resample on Get, we'd be able to access legit right padding values. */ - rpadding = SDL_stack_alloc(float, paddingsamples); - if (!rpadding) { - SDL_OutOfMemory(); - return 0; - } - SDL_memset(rpadding, '\0', paddingbytes); + SDL_assert(inbuf != ((const float *) outbuf)); /* SDL_AudioStreamPut() shouldn't allow in-place resamples. */ retval = SDL_ResampleAudio(chans, inrate, outrate, lpadding, rpadding, inbuf, inbuflen, outbuf, outbuflen); - SDL_stack_free(rpadding); - /* update our left padding with end of current input, for next run. */ - SDL_memcpy(lpadding, ((const Uint8 *) inbuf) + (inbuflen - paddingbytes), paddingbytes); - + SDL_memcpy(lpadding, inbufend - paddingbytes, paddingbytes); return retval; } static void SDL_ResetAudioStreamResampler(SDL_AudioStream *stream) { - /* set all the left padding to silence. */ - const int inrate = stream->src_rate; - const int outrate = stream->dst_rate; - const int chans = (int) stream->pre_resample_channels; - const int len = ResamplerPadding(inrate, outrate) * chans; + /* set all the padding to silence. */ + const int len = stream->resampler_padding_samples; SDL_memset(stream->resampler_state, '\0', len * sizeof (float)); } @@ -1293,6 +1273,7 @@ SDL_NewAudioStream(const SDL_AudioFormat src_format, the resampled data (!!! FIXME: decide if that works in practice, though!). */ pre_resample_channels = SDL_min(src_channels, dst_channels); + retval->first_run = SDL_TRUE; retval->src_sample_frame_size = (SDL_AUDIO_BITSIZE(src_format) / 8) * src_channels; retval->src_format = src_format; retval->src_channels = src_channels; @@ -1304,6 +1285,14 @@ SDL_NewAudioStream(const SDL_AudioFormat src_format, retval->pre_resample_channels = pre_resample_channels; retval->packetlen = packetlen; retval->rate_incr = ((double) dst_rate) / ((double) src_rate); + retval->resampler_padding_samples = ResamplerPadding(retval->src_rate, retval->dst_rate) * pre_resample_channels; + retval->resampler_padding = (float *) SDL_calloc(retval->resampler_padding_samples, sizeof (float)); + + if (retval->resampler_padding == NULL) { + SDL_FreeAudioStream(retval); + SDL_OutOfMemory(); + return NULL; + } /* Not resampling? It's an easy conversion (and maybe not even that!). */ if (src_rate == dst_rate) { @@ -1325,9 +1314,7 @@ SDL_NewAudioStream(const SDL_AudioFormat src_format, #endif if (!retval->resampler_func) { - const int chans = (int) pre_resample_channels; - const int len = ResamplerPadding(src_rate, dst_rate) * chans; - retval->resampler_state = SDL_calloc(len, sizeof (float)); + retval->resampler_state = SDL_calloc(retval->resampler_padding_samples, sizeof (float)); if (!retval->resampler_state) { SDL_FreeAudioStream(retval); SDL_OutOfMemory(); @@ -1366,7 +1353,12 @@ int SDL_AudioStreamPut(SDL_AudioStream *stream, const void *buf, const Uint32 _buflen) { int buflen = (int) _buflen; - const void *origbuf = buf; + int workbuflen; + Uint8 *workbuf; + Uint8 *resamplebuf = NULL; + int resamplebuflen = 0; + const int neededpaddingbytes = stream ? stream->resampler_padding_samples * sizeof (float) : 0; + int paddingbytes; /* !!! FIXME: several converters can take advantage of SIMD, but only !!! FIXME: if the data is aligned to 16 bytes. EnsureStreamBufferSize() @@ -1376,6 +1368,10 @@ SDL_AudioStreamPut(SDL_AudioStream *stream, const void *buf, const Uint32 _bufle !!! FIXME: isn't a multiple of 16. In these cases, we should chop off !!! FIXME: a few samples at the end and convert them separately. */ + #if DEBUG_AUDIOSTREAM + printf("AUDIOSTREAM: wants to put %d preconverted bytes\n", buflen); + #endif + if (!stream) { return SDL_InvalidParamError("stream"); } else if (!buf) { @@ -1384,60 +1380,114 @@ SDL_AudioStreamPut(SDL_AudioStream *stream, const void *buf, const Uint32 _bufle return 0; /* nothing to do. */ } else if ((buflen % stream->src_sample_frame_size) != 0) { return SDL_SetError("Can't add partial sample frames"); + } else if (buflen < (neededpaddingbytes * 2)) { + return SDL_SetError("Need to put a larger buffer"); } + /* no padding prepended on first run. */ + paddingbytes = stream->first_run ? 0 : neededpaddingbytes; + stream->first_run = SDL_FALSE; + + if (!stream->cvt_before_resampling.needed && + (stream->dst_rate == stream->src_rate) && + !stream->cvt_after_resampling.needed) { + #if DEBUG_AUDIOSTREAM + printf("AUDIOSTREAM: no conversion needed at all, queueing %d bytes.\n", buflen); + #endif + return SDL_WriteToDataQueue(stream->queue, buf, buflen); + } + + /* Make sure the work buffer can hold all the data we need at once... */ + workbuflen = buflen; if (stream->cvt_before_resampling.needed) { - const int workbuflen = buflen * stream->cvt_before_resampling.len_mult; /* will be "* 1" if not needed */ - Uint8 *workbuf = EnsureStreamBufferSize(stream, workbuflen); - if (workbuf == NULL) { - return -1; /* probably out of memory. */ - } - SDL_assert(buf == origbuf); - SDL_memcpy(workbuf, buf, buflen); - stream->cvt_before_resampling.buf = workbuf; + workbuflen *= stream->cvt_before_resampling.len_mult; + } + + if (stream->dst_rate != stream->src_rate) { + /* resamples can't happen in place, so make space for second buf. */ + const int framesize = stream->pre_resample_channels * sizeof (float); + const int frames = workbuflen / framesize; + resamplebuflen = ((int) SDL_ceil(frames * stream->rate_incr)) * framesize; + #if DEBUG_AUDIOSTREAM + printf("AUDIOSTREAM: will resample %d bytes to %d (ratio=%.6f)\n", workbuflen, resamplebuflen, stream->rate_incr); + #endif + workbuflen += resamplebuflen; + } + + if (stream->cvt_after_resampling.needed) { + /* !!! FIXME: buffer might be big enough already? */ + workbuflen *= stream->cvt_after_resampling.len_mult; + } + + workbuflen += neededpaddingbytes; + + #if DEBUG_AUDIOSTREAM + printf("AUDIOSTREAM: Putting %d bytes of preconverted audio, need %d byte work buffer\n", buflen, workbuflen); + #endif + + workbuf = EnsureStreamBufferSize(stream, workbuflen); + if (!workbuf) { + return -1; /* probably out of memory. */ + } + + resamplebuf = workbuf; /* default if not resampling. */ + + SDL_memcpy(workbuf + paddingbytes, buf, buflen); + + if (stream->cvt_before_resampling.needed) { + stream->cvt_before_resampling.buf = workbuf + paddingbytes; stream->cvt_before_resampling.len = buflen; if (SDL_ConvertAudio(&stream->cvt_before_resampling) == -1) { return -1; /* uhoh! */ } - buf = workbuf; buflen = stream->cvt_before_resampling.len_cvt; + + #if DEBUG_AUDIOSTREAM + printf("AUDIOSTREAM: After initial conversion we have %d bytes\n", buflen); + #endif } if (stream->dst_rate != stream->src_rate) { - const int workbuflen = buflen * ((int) SDL_ceil(stream->rate_incr)); - Uint8 *workbuf = EnsureStreamBufferSize(stream, workbuflen); - if (workbuf == NULL) { - return -1; /* probably out of memory. */ + /* save off some samples at the end; they are used for padding now so + the resampler is coherent and then used at the start of the next + put operation. Prepend last put operation's padding, too. */ + + /* prepend prior put's padding. :P */ + if (paddingbytes) { + SDL_memcpy(workbuf, stream->resampler_padding, paddingbytes); + buflen += paddingbytes; } - /* don't SDL_memcpy(workbuf, buf, buflen) here; our resampler can work inplace or not, - libsamplerate needs buffers to be separate; either way, avoid a copy here if possible. */ - if (buf != origbuf) { - buf = workbuf; /* in case we realloc()'d the pointer. */ - } - buflen = stream->resampler_func(stream, buf, buflen, workbuf, workbuflen); - buf = EnsureStreamBufferSize(stream, workbuflen); - SDL_assert(buf != NULL); /* shouldn't be growing, just aligning. */ + + /* save off the data at the end for the next run. */ + SDL_memcpy(stream->resampler_padding, workbuf + (buflen - neededpaddingbytes), neededpaddingbytes); + + resamplebuf = workbuf + buflen; /* skip to second piece of workbuf. */ + buflen = stream->resampler_func(stream, workbuf, buflen - neededpaddingbytes, resamplebuf, resamplebuflen); + + #if DEBUG_AUDIOSTREAM + printf("AUDIOSTREAM: After resampling we have %d bytes\n", buflen); + #endif } if (stream->cvt_after_resampling.needed) { - const int workbuflen = buflen * stream->cvt_after_resampling.len_mult; /* will be "* 1" if not needed */ - Uint8 *workbuf = EnsureStreamBufferSize(stream, workbuflen); - if (workbuf == NULL) { - return -1; /* probably out of memory. */ - } - if (buf == origbuf) { /* copy if we haven't before. */ - SDL_memcpy(workbuf, origbuf, buflen); - } - stream->cvt_after_resampling.buf = workbuf; + stream->cvt_after_resampling.buf = resamplebuf; stream->cvt_after_resampling.len = buflen; if (SDL_ConvertAudio(&stream->cvt_after_resampling) == -1) { return -1; /* uhoh! */ } - buf = workbuf; buflen = stream->cvt_after_resampling.len_cvt; + + #if DEBUG_AUDIOSTREAM + printf("AUDIOSTREAM: After final conversion we have %d bytes\n", buflen); + #endif } - return SDL_WriteToDataQueue(stream->queue, buf, buflen); + #if DEBUG_AUDIOSTREAM + printf("AUDIOSTREAM: Final output is %d bytes\n", buflen); + #endif + + /* resamplebuf holds the final output, even if we didn't resample. */ + return SDL_WriteToDataQueue(stream->queue, resamplebuf, buflen); } void @@ -1450,6 +1500,7 @@ SDL_AudioStreamClear(SDL_AudioStream *stream) if (stream->reset_resampler_func) { stream->reset_resampler_func(stream); } + stream->first_run = SDL_TRUE; } } @@ -1458,6 +1509,10 @@ SDL_AudioStreamClear(SDL_AudioStream *stream) int SDL_AudioStreamGet(SDL_AudioStream *stream, void *buf, const Uint32 len) { + #if DEBUG_AUDIOSTREAM + printf("AUDIOSTREAM: want to get %u converted bytes\n", (unsigned int) len); + #endif + if (!stream) { return SDL_InvalidParamError("stream"); } else if (!buf) { @@ -1488,6 +1543,7 @@ SDL_FreeAudioStream(SDL_AudioStream *stream) } SDL_FreeDataQueue(stream->queue); SDL_free(stream->work_buffer_base); + SDL_free(stream->resampler_padding); SDL_free(stream); } } From 90b63d4ac8b70b679de5768d1381daf25bcc1df5 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 10 Oct 2017 17:41:41 -0700 Subject: [PATCH 37/95] The event filter and event watch functions are now thread-safe --- src/events/SDL_events.c | 179 +++++++++++++++++++++++------------- src/events/SDL_events_c.h | 4 - src/joystick/SDL_joystick.c | 10 +- 3 files changed, 118 insertions(+), 75 deletions(-) diff --git a/src/events/SDL_events.c b/src/events/SDL_events.c index c87dc9930c..9b6fff8c4f 100644 --- a/src/events/SDL_events.c +++ b/src/events/SDL_events.c @@ -38,17 +38,15 @@ /* An arbitrary limit so we don't have unbounded growth */ #define SDL_MAX_QUEUED_EVENTS 65535 -/* Public data -- the event filter */ -SDL_EventFilter SDL_EventOK = NULL; -void *SDL_EventOKParam; - typedef struct SDL_EventWatcher { SDL_EventFilter callback; void *userdata; - struct SDL_EventWatcher *next; } SDL_EventWatcher; +static SDL_mutex *SDL_event_watchers_lock; +static SDL_EventWatcher SDL_EventOK; static SDL_EventWatcher *SDL_event_watchers = NULL; +static int SDL_event_watchers_count = 0; typedef struct { Uint32 bits[8]; @@ -367,12 +365,17 @@ SDL_StopEventLoop(void) SDL_disabled_events[i] = NULL; } - while (SDL_event_watchers) { - SDL_EventWatcher *tmp = SDL_event_watchers; - SDL_event_watchers = tmp->next; - SDL_free(tmp); + if (SDL_event_watchers_lock) { + SDL_UnlockMutex(SDL_event_watchers_lock); + SDL_DestroyMutex(SDL_event_watchers_lock); + SDL_event_watchers_lock = NULL; + } + if (SDL_event_watchers_count > 0) { + SDL_free(SDL_event_watchers); + SDL_event_watchers = NULL; + SDL_event_watchers_count = 0; } - SDL_EventOK = NULL; + SDL_zero(SDL_EventOK); if (SDL_EventQ.lock) { SDL_UnlockMutex(SDL_EventQ.lock); @@ -395,9 +398,16 @@ SDL_StartEventLoop(void) #if !SDL_THREADS_DISABLED if (!SDL_EventQ.lock) { SDL_EventQ.lock = SDL_CreateMutex(); + if (SDL_EventQ.lock == NULL) { + return -1; + } } - if (SDL_EventQ.lock == NULL) { - return -1; + + if (!SDL_event_watchers_lock) { + SDL_event_watchers_lock = SDL_CreateMutex(); + if (SDL_event_watchers_lock == NULL) { + return -1; + } } #endif /* !SDL_THREADS_DISABLED */ @@ -606,7 +616,7 @@ SDL_FlushEvents(Uint32 minType, Uint32 maxType) #endif /* Lock the event queue */ - if (SDL_EventQ.lock && SDL_LockMutex(SDL_EventQ.lock) == 0) { + if (!SDL_EventQ.lock || SDL_LockMutex(SDL_EventQ.lock) == 0) { SDL_EventEntry *entry, *next; Uint32 type; for (entry = SDL_EventQ.head; entry; entry = next) { @@ -616,7 +626,9 @@ SDL_FlushEvents(Uint32 minType, Uint32 maxType) SDL_CutEvent(entry); } } - SDL_UnlockMutex(SDL_EventQ.lock); + if (SDL_EventQ.lock) { + SDL_UnlockMutex(SDL_EventQ.lock); + } } } @@ -688,16 +700,41 @@ SDL_WaitEventTimeout(SDL_Event * event, int timeout) int SDL_PushEvent(SDL_Event * event) { - SDL_EventWatcher *curr; - event->common.timestamp = SDL_GetTicks(); - if (SDL_EventOK && !SDL_EventOK(SDL_EventOKParam, event)) { - return 0; - } + if (SDL_EventOK.callback || SDL_event_watchers_count != 0) { + SDL_EventWatcher event_ok; + SDL_EventWatcher *event_watchers = NULL; + int i, event_watchers_count = 0; + + if (!SDL_event_watchers_lock || SDL_LockMutex(SDL_event_watchers_lock) == 0) { + event_ok = SDL_EventOK; + + if (SDL_event_watchers_count > 0) { + event_watchers = SDL_stack_alloc(SDL_EventWatcher, SDL_event_watchers_count); + if (event_watchers) { + SDL_memcpy(event_watchers, SDL_event_watchers, SDL_event_watchers_count * sizeof(*event_watchers)); + event_watchers_count = SDL_event_watchers_count; + } + } + + if (SDL_event_watchers_lock) { + SDL_UnlockMutex(SDL_event_watchers_lock); + } + } else { + event_ok = SDL_EventOK; + } + + if (event_ok.callback && !event_ok.callback(event_ok.userdata, event)) { + return 0; + } - for (curr = SDL_event_watchers; curr; curr = curr->next) { - curr->callback(curr->userdata, event); + if (event_watchers_count > 0) { + for (i = 0; i < event_watchers_count; ++i) { + event_watchers[i].callback(event_watchers[i].userdata, event); + } + SDL_stack_free(event_watchers); + } } if (SDL_PeepEvents(event, 1, SDL_ADDEVENT, 0, 0) <= 0) { @@ -712,69 +749,83 @@ SDL_PushEvent(SDL_Event * event) void SDL_SetEventFilter(SDL_EventFilter filter, void *userdata) { - /* Set filter and discard pending events */ - SDL_EventOK = NULL; - SDL_FlushEvents(SDL_FIRSTEVENT, SDL_LASTEVENT); - SDL_EventOKParam = userdata; - SDL_EventOK = filter; + if (!SDL_event_watchers_lock || SDL_LockMutex(SDL_event_watchers_lock) == 0) { + /* Set filter and discard pending events */ + SDL_EventOK.callback = filter; + SDL_EventOK.userdata = userdata; + SDL_FlushEvents(SDL_FIRSTEVENT, SDL_LASTEVENT); + + if (SDL_event_watchers_lock) { + SDL_UnlockMutex(SDL_event_watchers_lock); + } + } } SDL_bool SDL_GetEventFilter(SDL_EventFilter * filter, void **userdata) { + SDL_EventWatcher event_ok; + + if (!SDL_event_watchers_lock || SDL_LockMutex(SDL_event_watchers_lock) == 0) { + event_ok = SDL_EventOK; + + if (SDL_event_watchers_lock) { + SDL_UnlockMutex(SDL_event_watchers_lock); + } + } else { + SDL_zero(event_ok); + } + if (filter) { - *filter = SDL_EventOK; + *filter = event_ok.callback; } if (userdata) { - *userdata = SDL_EventOKParam; + *userdata = event_ok.userdata; } - return SDL_EventOK ? SDL_TRUE : SDL_FALSE; + return event_ok.callback ? SDL_TRUE : SDL_FALSE; } -/* FIXME: This is not thread-safe yet */ void SDL_AddEventWatch(SDL_EventFilter filter, void *userdata) { - SDL_EventWatcher *watcher, *tail; - - watcher = (SDL_EventWatcher *)SDL_malloc(sizeof(*watcher)); - if (!watcher) { - /* Uh oh... */ - return; - } - - /* create the watcher */ - watcher->callback = filter; - watcher->userdata = userdata; - watcher->next = NULL; + if (!SDL_event_watchers_lock || SDL_LockMutex(SDL_event_watchers_lock) == 0) { + SDL_EventWatcher *event_watchers; + + event_watchers = SDL_realloc(SDL_event_watchers, (SDL_event_watchers_count + 1) * sizeof(event_watchers)); + if (event_watchers) { + SDL_EventWatcher *watcher; + + SDL_event_watchers = event_watchers; + watcher = &SDL_event_watchers[SDL_event_watchers_count]; + watcher->callback = filter; + watcher->userdata = userdata; + ++SDL_event_watchers_count; + } - /* add the watcher to the end of the list */ - if (SDL_event_watchers) { - for (tail = SDL_event_watchers; tail->next; tail = tail->next) { - continue; + if (SDL_event_watchers_lock) { + SDL_UnlockMutex(SDL_event_watchers_lock); } - tail->next = watcher; - } else { - SDL_event_watchers = watcher; } } -/* FIXME: This is not thread-safe yet */ void SDL_DelEventWatch(SDL_EventFilter filter, void *userdata) { - SDL_EventWatcher *prev = NULL; - SDL_EventWatcher *curr; - - for (curr = SDL_event_watchers; curr; prev = curr, curr = curr->next) { - if (curr->callback == filter && curr->userdata == userdata) { - if (prev) { - prev->next = curr->next; - } else { - SDL_event_watchers = curr->next; + if (!SDL_event_watchers_lock || SDL_LockMutex(SDL_event_watchers_lock) == 0) { + int i; + + for (i = 0; i < SDL_event_watchers_count; ++i) { + if (SDL_event_watchers[i].callback == filter && SDL_event_watchers[i].userdata == userdata) { + --SDL_event_watchers_count; + if (i < SDL_event_watchers_count) { + SDL_memcpy(&SDL_event_watchers[i], &SDL_event_watchers[i+1], (SDL_event_watchers_count - i) * sizeof(SDL_event_watchers[i])); + } + break; } - SDL_free(curr); - break; + } + + if (SDL_event_watchers_lock) { + SDL_UnlockMutex(SDL_event_watchers_lock); } } } @@ -782,7 +833,7 @@ SDL_DelEventWatch(SDL_EventFilter filter, void *userdata) void SDL_FilterEvents(SDL_EventFilter filter, void *userdata) { - if (SDL_EventQ.lock && SDL_LockMutex(SDL_EventQ.lock) == 0) { + if (!SDL_EventQ.lock || SDL_LockMutex(SDL_EventQ.lock) == 0) { SDL_EventEntry *entry, *next; for (entry = SDL_EventQ.head; entry; entry = next) { next = entry->next; @@ -790,7 +841,9 @@ SDL_FilterEvents(SDL_EventFilter filter, void *userdata) SDL_CutEvent(entry); } } - SDL_UnlockMutex(SDL_EventQ.lock); + if (SDL_EventQ.lock) { + SDL_UnlockMutex(SDL_EventQ.lock); + } } } diff --git a/src/events/SDL_events_c.h b/src/events/SDL_events_c.h index 83b0e143b3..56e48dd2cb 100644 --- a/src/events/SDL_events_c.h +++ b/src/events/SDL_events_c.h @@ -46,8 +46,4 @@ extern void SDL_QuitQuit(void); extern void SDL_SendPendingQuit(void); -/* The event filter function */ -extern SDL_EventFilter SDL_EventOK; -extern void *SDL_EventOKParam; - /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/joystick/SDL_joystick.c b/src/joystick/SDL_joystick.c index 4c4cae7578..b49b28ec3f 100644 --- a/src/joystick/SDL_joystick.c +++ b/src/joystick/SDL_joystick.c @@ -601,10 +601,7 @@ void SDL_PrivateJoystickAdded(int device_index) if (SDL_GetEventState(event.type) == SDL_ENABLE) { event.jdevice.which = device_index; - if ((SDL_EventOK == NULL) || - (*SDL_EventOK) (SDL_EventOKParam, &event)) { - SDL_PushEvent(&event); - } + SDL_PushEvent(&event); } #endif /* !SDL_EVENTS_DISABLED */ } @@ -647,10 +644,7 @@ void SDL_PrivateJoystickRemoved(SDL_JoystickID device_instance) if (SDL_GetEventState(event.type) == SDL_ENABLE) { event.jdevice.which = device_instance; - if ((SDL_EventOK == NULL) || - (*SDL_EventOK) (SDL_EventOKParam, &event)) { - SDL_PushEvent(&event); - } + SDL_PushEvent(&event); } UpdateEventsForDeviceRemoval(); From 54fd696a3667918e2938249f10d81b91bc995f33 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 10 Oct 2017 22:18:46 -0400 Subject: [PATCH 38/95] audio: Don't stack-allocate resampler padding. (I thought padding size ranged from 5 frames to ~30 frames (based around RESAMPLER_ZERO_CROSSINGS, which is 5), but it's actually between 512 and several thousands (based on RESAMPLER_SAMPLES_PER_ZERO_CROSSING)). It gets big fast when downsampling. --- src/audio/SDL_audiocvt.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/audio/SDL_audiocvt.c b/src/audio/SDL_audiocvt.c index 68e0b4cad0..073e7ee953 100644 --- a/src/audio/SDL_audiocvt.c +++ b/src/audio/SDL_audiocvt.c @@ -722,16 +722,15 @@ SDL_ResampleCVT(SDL_AudioCVT *cvt, const int chans, const SDL_AudioFormat format SDL_assert(format == AUDIO_F32SYS); /* we keep no streaming state here, so pad with silence on both ends. */ - padding = SDL_stack_alloc(float, paddingsamples); + padding = (float *) SDL_calloc(paddingsamples, sizeof (float)); if (!padding) { SDL_OutOfMemory(); return; } - SDL_memset(padding, '\0', paddingsamples * sizeof (float)); cvt->len_cvt = SDL_ResampleAudio(chans, inrate, outrate, padding, padding, src, srclen, dst, dstlen); - SDL_stack_free(padding); + SDL_free(padding); SDL_memcpy(cvt->buf, dst, cvt->len_cvt); /* !!! FIXME: remove this if we can get the resampler to work in-place again. */ From a782360ddafe2ca0565b46308274b3ab2e33baa9 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 10 Oct 2017 22:31:02 -0400 Subject: [PATCH 39/95] audio: SDL_ResampleCVT() should use memmove instead of memcpy. This copy can overlap. Fixes Bugzilla #3849. --- src/audio/SDL_audiocvt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/audio/SDL_audiocvt.c b/src/audio/SDL_audiocvt.c index 073e7ee953..c44485c17d 100644 --- a/src/audio/SDL_audiocvt.c +++ b/src/audio/SDL_audiocvt.c @@ -732,7 +732,7 @@ SDL_ResampleCVT(SDL_AudioCVT *cvt, const int chans, const SDL_AudioFormat format SDL_free(padding); - SDL_memcpy(cvt->buf, dst, cvt->len_cvt); /* !!! FIXME: remove this if we can get the resampler to work in-place again. */ + SDL_memmove(cvt->buf, dst, cvt->len_cvt); /* !!! FIXME: remove this if we can get the resampler to work in-place again. */ if (cvt->filters[++cvt->filter_index]) { cvt->filters[cvt->filter_index](cvt, format); From 3353b22dd5923dd1d1fe83ae4e43b281dd0784ee Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 10 Oct 2017 19:44:33 -0700 Subject: [PATCH 40/95] Fixed potentially calling a callback after it has been removed (and userdata possibly deleted) --- src/events/SDL_events.c | 66 +++++++++++++++++++++++++---------------- 1 file changed, 40 insertions(+), 26 deletions(-) diff --git a/src/events/SDL_events.c b/src/events/SDL_events.c index 9b6fff8c4f..27444d76ad 100644 --- a/src/events/SDL_events.c +++ b/src/events/SDL_events.c @@ -41,12 +41,15 @@ typedef struct SDL_EventWatcher { SDL_EventFilter callback; void *userdata; + SDL_bool removed; } SDL_EventWatcher; static SDL_mutex *SDL_event_watchers_lock; static SDL_EventWatcher SDL_EventOK; static SDL_EventWatcher *SDL_event_watchers = NULL; static int SDL_event_watchers_count = 0; +static SDL_bool SDL_event_watchers_dispatching = SDL_FALSE; +static SDL_bool SDL_event_watchers_removed = SDL_FALSE; typedef struct { Uint32 bits[8]; @@ -370,7 +373,7 @@ SDL_StopEventLoop(void) SDL_DestroyMutex(SDL_event_watchers_lock); SDL_event_watchers_lock = NULL; } - if (SDL_event_watchers_count > 0) { + if (SDL_event_watchers) { SDL_free(SDL_event_watchers); SDL_event_watchers = NULL; SDL_event_watchers_count = 0; @@ -703,37 +706,42 @@ SDL_PushEvent(SDL_Event * event) event->common.timestamp = SDL_GetTicks(); if (SDL_EventOK.callback || SDL_event_watchers_count != 0) { - SDL_EventWatcher event_ok; - SDL_EventWatcher *event_watchers = NULL; - int i, event_watchers_count = 0; - if (!SDL_event_watchers_lock || SDL_LockMutex(SDL_event_watchers_lock) == 0) { - event_ok = SDL_EventOK; + if (SDL_EventOK.callback && !SDL_EventOK.callback(SDL_EventOK.userdata, event)) { + if (SDL_event_watchers_lock) { + SDL_UnlockMutex(SDL_event_watchers_lock); + } + return 0; + } if (SDL_event_watchers_count > 0) { - event_watchers = SDL_stack_alloc(SDL_EventWatcher, SDL_event_watchers_count); - if (event_watchers) { - SDL_memcpy(event_watchers, SDL_event_watchers, SDL_event_watchers_count * sizeof(*event_watchers)); - event_watchers_count = SDL_event_watchers_count; + /* Make sure we only dispatch the current watcher list */ + int i, event_watchers_count = SDL_event_watchers_count; + + SDL_event_watchers_dispatching = SDL_TRUE; + for (i = 0; i < event_watchers_count; ++i) { + if (!SDL_event_watchers[i].removed) { + SDL_event_watchers[i].callback(SDL_event_watchers[i].userdata, event); + } + } + SDL_event_watchers_dispatching = SDL_FALSE; + + if (SDL_event_watchers_removed) { + for (i = SDL_event_watchers_count; i--; ) { + if (SDL_event_watchers[i].removed) { + --SDL_event_watchers_count; + if (i < SDL_event_watchers_count) { + SDL_memcpy(&SDL_event_watchers[i], &SDL_event_watchers[i+1], (SDL_event_watchers_count - i) * sizeof(SDL_event_watchers[i])); + } + } + } + SDL_event_watchers_removed = SDL_FALSE; } } if (SDL_event_watchers_lock) { SDL_UnlockMutex(SDL_event_watchers_lock); } - } else { - event_ok = SDL_EventOK; - } - - if (event_ok.callback && !event_ok.callback(event_ok.userdata, event)) { - return 0; - } - - if (event_watchers_count > 0) { - for (i = 0; i < event_watchers_count; ++i) { - event_watchers[i].callback(event_watchers[i].userdata, event); - } - SDL_stack_free(event_watchers); } } @@ -799,6 +807,7 @@ SDL_AddEventWatch(SDL_EventFilter filter, void *userdata) watcher = &SDL_event_watchers[SDL_event_watchers_count]; watcher->callback = filter; watcher->userdata = userdata; + watcher->removed = SDL_FALSE; ++SDL_event_watchers_count; } @@ -816,9 +825,14 @@ SDL_DelEventWatch(SDL_EventFilter filter, void *userdata) for (i = 0; i < SDL_event_watchers_count; ++i) { if (SDL_event_watchers[i].callback == filter && SDL_event_watchers[i].userdata == userdata) { - --SDL_event_watchers_count; - if (i < SDL_event_watchers_count) { - SDL_memcpy(&SDL_event_watchers[i], &SDL_event_watchers[i+1], (SDL_event_watchers_count - i) * sizeof(SDL_event_watchers[i])); + if (SDL_event_watchers_dispatching) { + SDL_event_watchers[i].removed = SDL_TRUE; + SDL_event_watchers_removed = SDL_TRUE; + } else { + --SDL_event_watchers_count; + if (i < SDL_event_watchers_count) { + SDL_memcpy(&SDL_event_watchers[i], &SDL_event_watchers[i+1], (SDL_event_watchers_count - i) * sizeof(SDL_event_watchers[i])); + } } break; } From d3e428ef1af4dbedbc8b26ef5c01b9d8744d41fe Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 10 Oct 2017 20:11:05 -0700 Subject: [PATCH 41/95] Changed overlapping memcpy to memmove --- src/events/SDL_events.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/events/SDL_events.c b/src/events/SDL_events.c index 27444d76ad..0049c9068a 100644 --- a/src/events/SDL_events.c +++ b/src/events/SDL_events.c @@ -705,7 +705,7 @@ SDL_PushEvent(SDL_Event * event) { event->common.timestamp = SDL_GetTicks(); - if (SDL_EventOK.callback || SDL_event_watchers_count != 0) { + if (SDL_EventOK.callback || SDL_event_watchers_count > 0) { if (!SDL_event_watchers_lock || SDL_LockMutex(SDL_event_watchers_lock) == 0) { if (SDL_EventOK.callback && !SDL_EventOK.callback(SDL_EventOK.userdata, event)) { if (SDL_event_watchers_lock) { @@ -731,7 +731,7 @@ SDL_PushEvent(SDL_Event * event) if (SDL_event_watchers[i].removed) { --SDL_event_watchers_count; if (i < SDL_event_watchers_count) { - SDL_memcpy(&SDL_event_watchers[i], &SDL_event_watchers[i+1], (SDL_event_watchers_count - i) * sizeof(SDL_event_watchers[i])); + SDL_memmove(&SDL_event_watchers[i], &SDL_event_watchers[i+1], (SDL_event_watchers_count - i) * sizeof(SDL_event_watchers[i])); } } } @@ -831,7 +831,7 @@ SDL_DelEventWatch(SDL_EventFilter filter, void *userdata) } else { --SDL_event_watchers_count; if (i < SDL_event_watchers_count) { - SDL_memcpy(&SDL_event_watchers[i], &SDL_event_watchers[i+1], (SDL_event_watchers_count - i) * sizeof(SDL_event_watchers[i])); + SDL_memmove(&SDL_event_watchers[i], &SDL_event_watchers[i+1], (SDL_event_watchers_count - i) * sizeof(SDL_event_watchers[i])); } } break; From 0a52f7050fe6560f44248fac4bd0912391cd1ee2 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 10 Oct 2017 20:16:52 -0700 Subject: [PATCH 42/95] Updated WhatsNew.txt for 2.0.7 changes --- WhatsNew.txt | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/WhatsNew.txt b/WhatsNew.txt index 38e0496234..9e845f5cd4 100644 --- a/WhatsNew.txt +++ b/WhatsNew.txt @@ -1,6 +1,22 @@ This is a list of major changes in SDL's version history. +--------------------------------------------------------------------------- +2.0.7: +--------------------------------------------------------------------------- + +General: +* Added locking functions for multi-threaded access to the joystick and game controller APIs: + SDL_LockJoysticks() + SDL_UnlockJoysticks() +* The following functions are now thread-safe: + SDL_SetEventFilter() + SDL_GetEventFilter() + SDL_AddEventWatch() + SDL_DelEventWatch() + + +General: --------------------------------------------------------------------------- 2.0.6: --------------------------------------------------------------------------- From a72a54166d7e92a10a58fc1514cc78caf64336dd Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 11 Oct 2017 01:37:11 -0400 Subject: [PATCH 43/95] audio: Fixed check for minimum audio stream put size. --- src/audio/SDL_audiocvt.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/audio/SDL_audiocvt.c b/src/audio/SDL_audiocvt.c index c44485c17d..5a7d799189 100644 --- a/src/audio/SDL_audiocvt.c +++ b/src/audio/SDL_audiocvt.c @@ -1356,7 +1356,7 @@ SDL_AudioStreamPut(SDL_AudioStream *stream, const void *buf, const Uint32 _bufle Uint8 *workbuf; Uint8 *resamplebuf = NULL; int resamplebuflen = 0; - const int neededpaddingbytes = stream ? stream->resampler_padding_samples * sizeof (float) : 0; + int neededpaddingbytes; int paddingbytes; /* !!! FIXME: several converters can take advantage of SIMD, but only @@ -1379,11 +1379,12 @@ SDL_AudioStreamPut(SDL_AudioStream *stream, const void *buf, const Uint32 _bufle return 0; /* nothing to do. */ } else if ((buflen % stream->src_sample_frame_size) != 0) { return SDL_SetError("Can't add partial sample frames"); - } else if (buflen < (neededpaddingbytes * 2)) { + } else if (buflen < ((stream->resampler_padding_samples / stream->pre_resample_channels) * stream->src_sample_frame_size)) { return SDL_SetError("Need to put a larger buffer"); } /* no padding prepended on first run. */ + neededpaddingbytes = stream->resampler_padding_samples * sizeof (float); paddingbytes = stream->first_run ? 0 : neededpaddingbytes; stream->first_run = SDL_FALSE; From dcc70ba6194c9235df5c526c2056cb9acadb4607 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 11 Oct 2017 02:03:05 -0400 Subject: [PATCH 44/95] audio: Make sure audio stream resampling doesn't overflow buffers. --- src/audio/SDL_audiocvt.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/audio/SDL_audiocvt.c b/src/audio/SDL_audiocvt.c index 5a7d799189..bbcad810d1 100644 --- a/src/audio/SDL_audiocvt.c +++ b/src/audio/SDL_audiocvt.c @@ -1224,6 +1224,7 @@ SDL_ResampleAudioStream(SDL_AudioStream *stream, const void *_inbuf, const int i const int paddingbytes = paddingsamples * sizeof (float); float *lpadding = (float *) stream->resampler_state; const float *rpadding = (const float *) inbufend; /* we set this up so there are valid padding samples at the end of the input buffer. */ + const int cpy = SDL_min(inbuflen, paddingbytes); int retval; SDL_assert(inbuf != ((const float *) outbuf)); /* SDL_AudioStreamPut() shouldn't allow in-place resamples. */ @@ -1231,7 +1232,7 @@ SDL_ResampleAudioStream(SDL_AudioStream *stream, const void *_inbuf, const int i retval = SDL_ResampleAudio(chans, inrate, outrate, lpadding, rpadding, inbuf, inbuflen, outbuf, outbuflen); /* update our left padding with end of current input, for next run. */ - SDL_memcpy(lpadding, inbufend - paddingbytes, paddingbytes); + SDL_memcpy((lpadding + paddingsamples) - (cpy / sizeof (float)), inbufend - cpy, cpy); return retval; } @@ -1462,14 +1463,19 @@ SDL_AudioStreamPut(SDL_AudioStream *stream, const void *buf, const Uint32 _bufle SDL_memcpy(stream->resampler_padding, workbuf + (buflen - neededpaddingbytes), neededpaddingbytes); resamplebuf = workbuf + buflen; /* skip to second piece of workbuf. */ - buflen = stream->resampler_func(stream, workbuf, buflen - neededpaddingbytes, resamplebuf, resamplebuflen); + SDL_assert(buflen >= neededpaddingbytes); + if (buflen > neededpaddingbytes) { + buflen = stream->resampler_func(stream, workbuf, buflen - neededpaddingbytes, resamplebuf, resamplebuflen); + } else { + buflen = 0; + } #if DEBUG_AUDIOSTREAM printf("AUDIOSTREAM: After resampling we have %d bytes\n", buflen); #endif } - if (stream->cvt_after_resampling.needed) { + if (stream->cvt_after_resampling.needed && (buflen > 0)) { stream->cvt_after_resampling.buf = resamplebuf; stream->cvt_after_resampling.len = buflen; if (SDL_ConvertAudio(&stream->cvt_after_resampling) == -1) { @@ -1487,7 +1493,7 @@ SDL_AudioStreamPut(SDL_AudioStream *stream, const void *buf, const Uint32 _bufle #endif /* resamplebuf holds the final output, even if we didn't resample. */ - return SDL_WriteToDataQueue(stream->queue, resamplebuf, buflen); + return buflen ? SDL_WriteToDataQueue(stream->queue, resamplebuf, buflen) : 0; } void From 00ee5384d16c0ef4240a81ec86713b8e27bbd369 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 11 Oct 2017 02:31:58 -0400 Subject: [PATCH 45/95] audio: Moved unchanging variable out of loop. --- src/audio/SDL_audiocvt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/audio/SDL_audiocvt.c b/src/audio/SDL_audiocvt.c index bbcad810d1..3fb2aad9b6 100644 --- a/src/audio/SDL_audiocvt.c +++ b/src/audio/SDL_audiocvt.c @@ -484,6 +484,7 @@ SDL_ResampleAudio(const int chans, const int inrate, const int outrate, const float *inbuf, const int inbuflen, float *outbuf, const int outbuflen) { + const double finrate = (double) inrate; const float outtimeincr = 1.0f / ((float) outrate); const float ratio = ((float) outrate) / ((float) inrate); const int paddinglen = ResamplerPadding(inrate, outrate); @@ -498,7 +499,6 @@ SDL_ResampleAudio(const int chans, const int inrate, const int outrate, for (i = 0; i < outframes; i++) { const int srcindex = (int) (outtime * inrate); - const float finrate = (float) inrate; const float intime = ((float) srcindex) / finrate; const float innexttime = ((float) (srcindex + 1)) / finrate; From 3c9c242fe0b11ccd1a6e2a85bd142d3bd6dbfb62 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 11 Oct 2017 02:33:55 -0400 Subject: [PATCH 46/95] audio: clamp resampler interpolation values to prevent buffer overflow. Partially fixes Bugzilla #3848. --- src/audio/SDL_audiocvt.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/audio/SDL_audiocvt.c b/src/audio/SDL_audiocvt.c index 3fb2aad9b6..4808e67294 100644 --- a/src/audio/SDL_audiocvt.c +++ b/src/audio/SDL_audiocvt.c @@ -501,10 +501,9 @@ SDL_ResampleAudio(const int chans, const int inrate, const int outrate, const int srcindex = (int) (outtime * inrate); const float intime = ((float) srcindex) / finrate; const float innexttime = ((float) (srcindex + 1)) / finrate; - - const float interpolation1 = 1.0f - (innexttime - outtime) / (innexttime - intime); + const float interpolation1 = SDL_max(0.0f, 1.0f - (innexttime - outtime) / (innexttime - intime)); const int filterindex1 = (int) (interpolation1 * RESAMPLER_SAMPLES_PER_ZERO_CROSSING); - const float interpolation2 = 1.0f - interpolation1; + const float interpolation2 = SDL_max(0.0f, 1.0f - interpolation1); const int filterindex2 = (int) (interpolation2 * RESAMPLER_SAMPLES_PER_ZERO_CROSSING); for (chan = 0; chan < chans; chan++) { From f27c9c108399296ec242c17d442f9c8bc67b6d6f Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 11 Oct 2017 11:43:35 -0400 Subject: [PATCH 47/95] audio: calculate resampling time directly, don't increment (thanks, Eric!). Fixes buffer overruns as floating point errors accumulate. Partially fixes Bugzilla #3848. --- src/audio/SDL_audiocvt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/audio/SDL_audiocvt.c b/src/audio/SDL_audiocvt.c index 4808e67294..9027799c0c 100644 --- a/src/audio/SDL_audiocvt.c +++ b/src/audio/SDL_audiocvt.c @@ -527,7 +527,7 @@ SDL_ResampleAudio(const int chans, const int inrate, const int outrate, *(dst++) = outsample; } - outtime += outtimeincr; + outtime = i * outtimeincr; } return outframes * chans * sizeof (float); From 53fd79c45813ac00300eb3fd4ef5643e550cf6a0 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 11 Oct 2017 11:51:14 -0400 Subject: [PATCH 48/95] audio: Moved the resampler state up to double precision. Fixes more buffer overflows. --- src/audio/SDL_audiocvt.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/audio/SDL_audiocvt.c b/src/audio/SDL_audiocvt.c index 9027799c0c..9bfe6d5d1f 100644 --- a/src/audio/SDL_audiocvt.c +++ b/src/audio/SDL_audiocvt.c @@ -485,8 +485,8 @@ SDL_ResampleAudio(const int chans, const int inrate, const int outrate, float *outbuf, const int outbuflen) { const double finrate = (double) inrate; - const float outtimeincr = 1.0f / ((float) outrate); - const float ratio = ((float) outrate) / ((float) inrate); + const double outtimeincr = 1.0 / ((float) outrate); + const double ratio = ((float) outrate) / ((float) inrate); const int paddinglen = ResamplerPadding(inrate, outrate); const int framelen = chans * (int)sizeof (float); const int inframes = inbuflen / framelen; @@ -494,16 +494,16 @@ SDL_ResampleAudio(const int chans, const int inrate, const int outrate, const int maxoutframes = outbuflen / framelen; const int outframes = SDL_min(wantedoutframes, maxoutframes); float *dst = outbuf; - float outtime = 0.0f; + double outtime = 0.0; int i, j, chan; for (i = 0; i < outframes; i++) { const int srcindex = (int) (outtime * inrate); - const float intime = ((float) srcindex) / finrate; - const float innexttime = ((float) (srcindex + 1)) / finrate; - const float interpolation1 = SDL_max(0.0f, 1.0f - (innexttime - outtime) / (innexttime - intime)); + const double intime = ((double) srcindex) / finrate; + const double innexttime = ((double) (srcindex + 1)) / finrate; + const double interpolation1 = 1.0 - ((innexttime - outtime) / (innexttime - intime)); const int filterindex1 = (int) (interpolation1 * RESAMPLER_SAMPLES_PER_ZERO_CROSSING); - const float interpolation2 = SDL_max(0.0f, 1.0f - interpolation1); + const double interpolation2 = 1.0 - interpolation1; const int filterindex2 = (int) (interpolation2 * RESAMPLER_SAMPLES_PER_ZERO_CROSSING); for (chan = 0; chan < chans; chan++) { From b69705bfe0ea06b09c1c439761eb5c672cb55336 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 11 Oct 2017 12:07:43 -0400 Subject: [PATCH 49/95] audio: Turns out the accumulation errors sound better. :/ Moving to double fixed the overflows, but using "time = i * incr" instead of "time += incr" causes clicks in the output. --- src/audio/SDL_audiocvt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/audio/SDL_audiocvt.c b/src/audio/SDL_audiocvt.c index 9bfe6d5d1f..4c8db0fc5a 100644 --- a/src/audio/SDL_audiocvt.c +++ b/src/audio/SDL_audiocvt.c @@ -527,7 +527,7 @@ SDL_ResampleAudio(const int chans, const int inrate, const int outrate, *(dst++) = outsample; } - outtime = i * outtimeincr; + outtime += outtimeincr; } return outframes * chans * sizeof (float); From 5072035254d84eca0b77d8cf557888cb3f31b4d8 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Wed, 11 Oct 2017 13:26:58 -0700 Subject: [PATCH 50/95] Fixed size in realloc --- src/events/SDL_events.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/events/SDL_events.c b/src/events/SDL_events.c index 0049c9068a..777c27399d 100644 --- a/src/events/SDL_events.c +++ b/src/events/SDL_events.c @@ -799,7 +799,7 @@ SDL_AddEventWatch(SDL_EventFilter filter, void *userdata) if (!SDL_event_watchers_lock || SDL_LockMutex(SDL_event_watchers_lock) == 0) { SDL_EventWatcher *event_watchers; - event_watchers = SDL_realloc(SDL_event_watchers, (SDL_event_watchers_count + 1) * sizeof(event_watchers)); + event_watchers = SDL_realloc(SDL_event_watchers, (SDL_event_watchers_count + 1) * sizeof(*event_watchers)); if (event_watchers) { SDL_EventWatcher *watcher; From 0433f3984e062f173e8e252158388d78591e315d Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Wed, 11 Oct 2017 13:31:21 -0700 Subject: [PATCH 51/95] Fixed bug 3871 - Touch events are not normalised on X11 Trent Gamblin The documentation for SDL_TouchFingerEvent says that the x and y coordinates are normalised between 0-1. I've found that to be true on Windows, Android and iOS but on X11 they are in pixel coordinates. This patch fixes the issue. This was the cleanest way I could do it with what was available without changing things around a lot but you may know a better way. --- src/video/x11/SDL_x11xinput2.c | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/src/video/x11/SDL_x11xinput2.c b/src/video/x11/SDL_x11xinput2.c index 654fb8445b..a4a588201d 100644 --- a/src/video/x11/SDL_x11xinput2.c +++ b/src/video/x11/SDL_x11xinput2.c @@ -73,6 +73,24 @@ xinput2_version_atleast(const int version, const int wantmajor, const int wantmi { return ( version >= ((wantmajor * 1000) + wantminor) ); } + +static void +xinput2_normalize_touch_coordinates(SDL_VideoData *videodata, Window window, + double in_x, double in_y, float *out_x, float *out_y) +{ + int i; + for (i = 0; i < videodata->numwindows; i++) { + SDL_WindowData *d = videodata->windowlist[i]; + if (d->xwindow == window) { + *out_x = in_x / (d->window->w-1); + *out_y = in_y / (d->window->h-1); + return; + } + } + // couldn't find the window... + *out_x = in_x; + *out_y = in_y; +} #endif /* SDL_VIDEO_DRIVER_X11_XINPUT2 */ void @@ -171,22 +189,31 @@ X11_HandleXinput2Event(SDL_VideoData *videodata,XGenericEventCookie *cookie) #if SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH case XI_TouchBegin: { const XIDeviceEvent *xev = (const XIDeviceEvent *) cookie->data; + float x, y; + xinput2_normalize_touch_coordinates(videodata, xev->event, + xev->event_x, xev->event_y, &x, &y); SDL_SendTouch(xev->sourceid,xev->detail, - SDL_TRUE, xev->event_x, xev->event_y, 1.0); + SDL_TRUE, x, y, 1.0); return 1; } break; case XI_TouchEnd: { const XIDeviceEvent *xev = (const XIDeviceEvent *) cookie->data; + float x, y; + xinput2_normalize_touch_coordinates(videodata, xev->event, + xev->event_x, xev->event_y, &x, &y); SDL_SendTouch(xev->sourceid,xev->detail, - SDL_FALSE, xev->event_x, xev->event_y, 1.0); + SDL_FALSE, x, y, 1.0); return 1; } break; case XI_TouchUpdate: { const XIDeviceEvent *xev = (const XIDeviceEvent *) cookie->data; + float x, y; + xinput2_normalize_touch_coordinates(videodata, xev->event, + xev->event_x, xev->event_y, &x, &y); SDL_SendTouchMotion(xev->sourceid,xev->detail, - xev->event_x, xev->event_y, 1.0); + x, y, 1.0); return 1; } break; From cd42145c36b3dd9cb9caabdaf7462d52c8824358 Mon Sep 17 00:00:00 2001 From: Ethan Lee Date: Tue, 10 Oct 2017 20:22:15 -0400 Subject: [PATCH 52/95] Check SDL_UDEV_DYNAMIC first, then SDL_UDEV_LIBS separately --- src/core/linux/SDL_udev.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/core/linux/SDL_udev.c b/src/core/linux/SDL_udev.c index 502490b70f..37bc4224f8 100644 --- a/src/core/linux/SDL_udev.c +++ b/src/core/linux/SDL_udev.c @@ -36,14 +36,7 @@ #include "SDL_timer.h" #include "../unix/SDL_poll.h" -static const char *SDL_UDEV_LIBS[] = { -#ifdef SDL_UDEV_DYNAMIC - SDL_UDEV_DYNAMIC -#else - "libudev.so.1", - "libudev.so.0" -#endif -}; +static const char *SDL_UDEV_LIBS[] = { "libudev.so.1", "libudev.so.0" }; #define _THIS SDL_UDEV_PrivateData *_this static _THIS = NULL; @@ -261,6 +254,19 @@ SDL_UDEV_LoadLibrary(void) return 0; } +#ifdef SDL_UDEV_DYNAMIC + /* Check for the build environment's libudev first */ + if (_this->udev_handle == NULL) { + _this->udev_handle = SDL_LoadObject(SDL_UDEV_DYNAMIC); + if (_this->udev_handle != NULL) { + retval = SDL_UDEV_load_syms(); + if (retval < 0) { + SDL_UDEV_UnloadLibrary(); + } + } + } +#endif + if (_this->udev_handle == NULL) { for( i = 0 ; i < SDL_arraysize(SDL_UDEV_LIBS); i++) { _this->udev_handle = SDL_LoadObject(SDL_UDEV_LIBS[i]); From c014b9d7636aa5a1a91049a0449025d640179fb5 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 12 Oct 2017 08:08:04 -0700 Subject: [PATCH 53/95] Updated version to 2.0.7 --- CMakeLists.txt | 4 ++-- Xcode/SDL/Info-Framework.plist | 4 ++-- Xcode/SDL/SDL.xcodeproj/project.pbxproj | 4 ++-- configure | 4 ++-- configure.in | 4 ++-- debian/changelog | 6 ++++++ include/SDL_version.h | 2 +- src/main/windows/version.rc | 8 ++++---- 8 files changed, 21 insertions(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9d363aec0d..c13794a389 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,9 +42,9 @@ include(${SDL2_SOURCE_DIR}/cmake/sdlchecks.cmake) # set SDL_BINARY_AGE and SDL_INTERFACE_AGE to 0. set(SDL_MAJOR_VERSION 2) set(SDL_MINOR_VERSION 0) -set(SDL_MICRO_VERSION 6) +set(SDL_MICRO_VERSION 7) set(SDL_INTERFACE_AGE 0) -set(SDL_BINARY_AGE 6) +set(SDL_BINARY_AGE 7) set(SDL_VERSION "${SDL_MAJOR_VERSION}.${SDL_MINOR_VERSION}.${SDL_MICRO_VERSION}") # Set defaults preventing destination file conflicts diff --git a/Xcode/SDL/Info-Framework.plist b/Xcode/SDL/Info-Framework.plist index 0be3ae5df2..a509c89eb2 100644 --- a/Xcode/SDL/Info-Framework.plist +++ b/Xcode/SDL/Info-Framework.plist @@ -19,10 +19,10 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 2.0.6 + 2.0.7 CFBundleSignature SDLX CFBundleVersion - 2.0.6 + 2.0.7 diff --git a/Xcode/SDL/SDL.xcodeproj/project.pbxproj b/Xcode/SDL/SDL.xcodeproj/project.pbxproj index 856939f62e..4673d2c416 100755 --- a/Xcode/SDL/SDL.xcodeproj/project.pbxproj +++ b/Xcode/SDL/SDL.xcodeproj/project.pbxproj @@ -2846,7 +2846,7 @@ CLANG_LINK_OBJC_RUNTIME = NO; COMBINE_HIDPI_IMAGES = YES; DYLIB_COMPATIBILITY_VERSION = 1.0.0; - DYLIB_CURRENT_VERSION = 7.0.0; + DYLIB_CURRENT_VERSION = 8.0.0; FRAMEWORK_VERSION = A; HEADER_SEARCH_PATHS = ( /usr/X11R6/include, @@ -2937,7 +2937,7 @@ CLANG_LINK_OBJC_RUNTIME = NO; COMBINE_HIDPI_IMAGES = YES; DYLIB_COMPATIBILITY_VERSION = 1.0.0; - DYLIB_CURRENT_VERSION = 7.0.0; + DYLIB_CURRENT_VERSION = 8.0.0; FRAMEWORK_VERSION = A; HEADER_SEARCH_PATHS = ( /usr/X11R6/include, diff --git a/configure b/configure index 1cb707e2b7..fc0d3466cd 100755 --- a/configure +++ b/configure @@ -2710,9 +2710,9 @@ orig_CFLAGS="$CFLAGS" # SDL_MAJOR_VERSION=2 SDL_MINOR_VERSION=0 -SDL_MICRO_VERSION=6 +SDL_MICRO_VERSION=7 SDL_INTERFACE_AGE=0 -SDL_BINARY_AGE=6 +SDL_BINARY_AGE=7 SDL_VERSION=$SDL_MAJOR_VERSION.$SDL_MINOR_VERSION.$SDL_MICRO_VERSION diff --git a/configure.in b/configure.in index 33572d7a15..a4b88f9d16 100644 --- a/configure.in +++ b/configure.in @@ -20,9 +20,9 @@ dnl Set various version strings - taken gratefully from the GTk sources # SDL_MAJOR_VERSION=2 SDL_MINOR_VERSION=0 -SDL_MICRO_VERSION=6 +SDL_MICRO_VERSION=7 SDL_INTERFACE_AGE=0 -SDL_BINARY_AGE=6 +SDL_BINARY_AGE=7 SDL_VERSION=$SDL_MAJOR_VERSION.$SDL_MINOR_VERSION.$SDL_MICRO_VERSION AC_SUBST(SDL_MAJOR_VERSION) diff --git a/debian/changelog b/debian/changelog index 48c9d75392..e9786f7f81 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +libsdl2 (2.0.7ubuntu1) UNRELEASED; urgency=low + + * Updated SDL to version 2.0.7 + + -- Sam Lantinga Thu, 12 Oct 2017 08:01:16 -0800 + libsdl2 (2.0.6ubuntu1) UNRELEASED; urgency=low * Updated SDL to version 2.0.6 diff --git a/include/SDL_version.h b/include/SDL_version.h index 8471b65438..5b4c402486 100644 --- a/include/SDL_version.h +++ b/include/SDL_version.h @@ -59,7 +59,7 @@ typedef struct SDL_version */ #define SDL_MAJOR_VERSION 2 #define SDL_MINOR_VERSION 0 -#define SDL_PATCHLEVEL 6 +#define SDL_PATCHLEVEL 7 /** * \brief Macro to determine SDL version program was compiled against. diff --git a/src/main/windows/version.rc b/src/main/windows/version.rc index f02cc9055d..b8968ce6e0 100644 --- a/src/main/windows/version.rc +++ b/src/main/windows/version.rc @@ -9,8 +9,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // VS_VERSION_INFO VERSIONINFO - FILEVERSION 2,0,6,0 - PRODUCTVERSION 2,0,6,0 + FILEVERSION 2,0,7,0 + PRODUCTVERSION 2,0,7,0 FILEFLAGSMASK 0x3fL FILEFLAGS 0x0L FILEOS 0x40004L @@ -23,12 +23,12 @@ BEGIN BEGIN VALUE "CompanyName", "\0" VALUE "FileDescription", "SDL\0" - VALUE "FileVersion", "2, 0, 6, 0\0" + VALUE "FileVersion", "2, 0, 7, 0\0" VALUE "InternalName", "SDL\0" VALUE "LegalCopyright", "Copyright © 2017 Sam Lantinga\0" VALUE "OriginalFilename", "SDL2.dll\0" VALUE "ProductName", "Simple DirectMedia Layer\0" - VALUE "ProductVersion", "2, 0, 6, 0\0" + VALUE "ProductVersion", "2, 0, 7, 0\0" END END BLOCK "VarFileInfo" From e888398acf2e8b064b973788658e22ec1a8b889e Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Thu, 12 Oct 2017 14:28:05 +0300 Subject: [PATCH 54/95] make sure that SDL_malloc(0) or SDL_calloc(0,x) doesn't return NULL. --- src/stdlib/SDL_malloc.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/stdlib/SDL_malloc.c b/src/stdlib/SDL_malloc.c index db3b107857..de7f13a945 100644 --- a/src/stdlib/SDL_malloc.c +++ b/src/stdlib/SDL_malloc.c @@ -33,11 +33,17 @@ void *SDL_malloc(size_t size) { + if (!size) { + return malloc(1); + } return malloc(size); } void *SDL_calloc(size_t nmemb, size_t size) { + if (!size || !nmemb) { + return calloc(1,1); + } return calloc(nmemb, size); } From fecee6e6096fc8660e330c7edfa9751c2d67bb1a Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 12 Oct 2017 08:27:22 -0700 Subject: [PATCH 55/95] Fixed divide by zero with a 1x1 sized window --- src/video/x11/SDL_x11xinput2.c | 44 ++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/src/video/x11/SDL_x11xinput2.c b/src/video/x11/SDL_x11xinput2.c index a4a588201d..a602b2a63d 100644 --- a/src/video/x11/SDL_x11xinput2.c +++ b/src/video/x11/SDL_x11xinput2.c @@ -74,23 +74,34 @@ xinput2_version_atleast(const int version, const int wantmajor, const int wantmi return ( version >= ((wantmajor * 1000) + wantminor) ); } +#if SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH static void xinput2_normalize_touch_coordinates(SDL_VideoData *videodata, Window window, double in_x, double in_y, float *out_x, float *out_y) { - int i; - for (i = 0; i < videodata->numwindows; i++) { - SDL_WindowData *d = videodata->windowlist[i]; - if (d->xwindow == window) { - *out_x = in_x / (d->window->w-1); - *out_y = in_y / (d->window->h-1); - return; - } - } - // couldn't find the window... - *out_x = in_x; - *out_y = in_y; + int i; + for (i = 0; i < videodata->numwindows; i++) { + SDL_WindowData *d = videodata->windowlist[i]; + if (d->xwindow == window) { + if (d->window->w == 1) { + *out_x = 0.5f; + } else { + *out_x = in_x / (d->window->w - 1); + } + if (d->window->h == 1) { + *out_y = 0.5f; + } else { + *out_y = in_y / (d->window->h - 1); + } + return; + } + } + // couldn't find the window... + *out_x = in_x; + *out_y = in_y; } +#endif /* SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH */ + #endif /* SDL_VIDEO_DRIVER_X11_XINPUT2 */ void @@ -192,8 +203,7 @@ X11_HandleXinput2Event(SDL_VideoData *videodata,XGenericEventCookie *cookie) float x, y; xinput2_normalize_touch_coordinates(videodata, xev->event, xev->event_x, xev->event_y, &x, &y); - SDL_SendTouch(xev->sourceid,xev->detail, - SDL_TRUE, x, y, 1.0); + SDL_SendTouch(xev->sourceid,xev->detail, SDL_TRUE, x, y, 1.0); return 1; } break; @@ -202,8 +212,7 @@ X11_HandleXinput2Event(SDL_VideoData *videodata,XGenericEventCookie *cookie) float x, y; xinput2_normalize_touch_coordinates(videodata, xev->event, xev->event_x, xev->event_y, &x, &y); - SDL_SendTouch(xev->sourceid,xev->detail, - SDL_FALSE, x, y, 1.0); + SDL_SendTouch(xev->sourceid,xev->detail, SDL_FALSE, x, y, 1.0); return 1; } break; @@ -212,8 +221,7 @@ X11_HandleXinput2Event(SDL_VideoData *videodata,XGenericEventCookie *cookie) float x, y; xinput2_normalize_touch_coordinates(videodata, xev->event, xev->event_x, xev->event_y, &x, &y); - SDL_SendTouchMotion(xev->sourceid,xev->detail, - x, y, 1.0); + SDL_SendTouchMotion(xev->sourceid,xev->detail, x, y, 1.0); return 1; } break; From 8543eb4802ea53247764455ddea0365560099cc5 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 12 Oct 2017 08:37:55 -0700 Subject: [PATCH 56/95] Normalize touch events to the render viewport (thanks Sylvain!) --- src/render/SDL_render.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/render/SDL_render.c b/src/render/SDL_render.c index 71f707c1ac..7a4dfeffd8 100644 --- a/src/render/SDL_render.c +++ b/src/render/SDL_render.c @@ -219,7 +219,35 @@ SDL_RendererEventWatch(void *userdata, SDL_Event *event) event->button.x = (int)(event->button.x / (renderer->scale.x * renderer->dpi_scale.x)); event->button.y = (int)(event->button.y / (renderer->scale.y * renderer->dpi_scale.y)); } + } else if (event->type == SDL_FINGERDOWN || + event->type == SDL_FINGERUP || + event->type == SDL_FINGERMOTION) { + if (renderer->logical_w) { + int w = 1; + int h = 1; + SDL_GetRendererOutputSize(renderer, &w, &h); + + event->tfinger.x *= (w - 1); + event->tfinger.y *= (h - 1); + + event->tfinger.x -= (renderer->viewport.x * renderer->dpi_scale.x); + event->tfinger.y -= (renderer->viewport.y * renderer->dpi_scale.y); + event->tfinger.x = (event->tfinger.x / (renderer->scale.x * renderer->dpi_scale.x)); + event->tfinger.y = (event->tfinger.y / (renderer->scale.y * renderer->dpi_scale.y)); + + if (renderer->logical_w > 1) { + event->tfinger.x = event->tfinger.x / (renderer->logical_w - 1); + } else { + event->tfinger.x = 0.5f; + } + if (renderer->logical_h > 1) { + event->tfinger.y = event->tfinger.y / (renderer->logical_h - 1); + } else { + event->tfinger.y = 0.5f; + } + } } + return 0; } From 876cd3521e60e41d8efda2f645aabe00778e11d9 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 12 Oct 2017 08:41:11 -0700 Subject: [PATCH 57/95] Fixed bug 3874 - Compiler warnings SDL_Surface.c and SDL_cocoakeyboard.m --- src/test/SDL_test_common.c | 2 +- src/video/cocoa/SDL_cocoakeyboard.m | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/SDL_test_common.c b/src/test/SDL_test_common.c index b536e3808d..780993c5b9 100644 --- a/src/test/SDL_test_common.c +++ b/src/test/SDL_test_common.c @@ -939,7 +939,7 @@ SDLTest_CommonInit(SDLTest_CommonState * state) } /* Add resize/drag areas for windows that are borderless and resizable */ - if ((state->window_flags & SDL_WINDOW_RESIZABLE|SDL_WINDOW_BORDERLESS) == + if ((state->window_flags & (SDL_WINDOW_RESIZABLE|SDL_WINDOW_BORDERLESS)) == (SDL_WINDOW_RESIZABLE|SDL_WINDOW_BORDERLESS)) { SDL_SetWindowHitTest(state->windows[i], SDLTest_ExampleHitTestCallback, NULL); } diff --git a/src/video/cocoa/SDL_cocoakeyboard.m b/src/video/cocoa/SDL_cocoakeyboard.m index b2ce5a31d1..e1d100a2bd 100644 --- a/src/video/cocoa/SDL_cocoakeyboard.m +++ b/src/video/cocoa/SDL_cocoakeyboard.m @@ -93,7 +93,7 @@ - (NSRange)selectedRange return _selectedRange; } -- (void)setMarkedText:(id)aString selectedRange:(NSRange)selectedRange replacementRange:(NSRange)replacementRange; +- (void)setMarkedText:(id)aString selectedRange:(NSRange)selectedRange replacementRange:(NSRange)replacementRange { if ([aString isKindOfClass:[NSAttributedString class]]) { aString = [aString string]; @@ -127,7 +127,7 @@ - (void)unmarkText SDL_SendEditingText("", 0, 0); } -- (NSRect)firstRectForCharacterRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange; +- (NSRect)firstRectForCharacterRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange { NSWindow *window = [self window]; NSRect contentRect = [window contentRectForFrameRect:[window frame]]; @@ -155,7 +155,7 @@ - (NSRect)firstRectForCharacterRange:(NSRange)aRange actualRange:(NSRangePointer return rect; } -- (NSAttributedString *)attributedSubstringForProposedRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange; +- (NSAttributedString *)attributedSubstringForProposedRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange { DEBUG_IME(@"attributedSubstringFromRange: (%d, %d)", aRange.location, aRange.length); return nil; From 966dcda7835258cea27a8784eb28781ed1fd83bd Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 12 Oct 2017 08:44:45 -0700 Subject: [PATCH 58/95] Fixed bug 3867 - Can't find install_manifest.txt when running 'uninstall' target Steve Robinson When I try to build the 'uninstall' target in CMake when SDL2 is added to a subdirectory of my project, I get this error: 1>CMake Error at cmake_uninstall.cmake:2 (message): 1> Cannot find install manifest: 1> "D:/Code/sdl2-tutorial/_build/3rdparty/SDL2/SDL2-2.0.6/install_manifest.txt" The install_manifest.txt is actually in the top-level binary directory, not the project-specific binary directory. To fix it, change all instances of: CMAKE_CURRENT_BINARY_DIR To: CMAKE_BINARY_DIR In: cmake_uninstall.cmake.in --- cmake_uninstall.cmake.in | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cmake_uninstall.cmake.in b/cmake_uninstall.cmake.in index e3a5a4be9f..1761561b3b 100644 --- a/cmake_uninstall.cmake.in +++ b/cmake_uninstall.cmake.in @@ -1,8 +1,8 @@ -if (NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") - message(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"") -endif(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") +if (NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt") + message(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_BINARY_DIR@/install_manifest.txt\"") +endif(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt") -file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files) +file(READ "@CMAKE_BINARY_DIR@/install_manifest.txt" files) string(REGEX REPLACE "\n" ";" files "${files}") foreach (file ${files}) message(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"") From 99af9604ad658ca5cc366427b223d2b5127801c3 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 12 Oct 2017 08:47:02 -0700 Subject: [PATCH 59/95] Fixed bug 3866 - CMake error when trying to make the 'uninstall' target when it already exists Steve Robinson In my project, the 'uninstall' target is already created by the glew library. I get this error when SDL2 tries to create it: CMake Error at _build/3rdparty/SDL2/SDL2-2.0.6/CMakeLists.txt:1816 (add_custom_target): add_custom_target cannot create target "uninstall" because another target with the same name already exists. The existing target is a custom target created in source directory "D:/Code/sdl2-tutorial/_build/3rdparty/glew/glew-2.1.0/build/cmake". See documentation for policy CMP0002 for more details. To fix it, go to the bottom of the SDL2 CMakeLists.txt file. Add an if statement to check for the existence of the target before creating it. The end result looks like this: if(NOT TARGET uninstall) configure_file( "${CMAKE_CURRENT_SOURCE_DIR}/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() This is how the glew library deals with this possibility in their CMakeLists.txt file. --- CMakeLists.txt | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c13794a389..1a36967efa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1808,10 +1808,12 @@ endif() ##### Uninstall target ##### -configure_file( - "${CMAKE_CURRENT_SOURCE_DIR}/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) +if(NOT TARGET uninstall) + configure_file( + "${CMAKE_CURRENT_SOURCE_DIR}/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() From 0b038795fbf2acc53ecebe9167e09ce4e40f3f0f Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 12 Oct 2017 13:28:48 -0700 Subject: [PATCH 60/95] Fixed memory leak in Cocoa mouse code The video quit call cleans up the mouse cursor driver data, which happens after mouse quit --- src/events/SDL_mouse.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/events/SDL_mouse.c b/src/events/SDL_mouse.c index 7a7bb2e4a7..794eafe1e6 100644 --- a/src/events/SDL_mouse.c +++ b/src/events/SDL_mouse.c @@ -81,6 +81,8 @@ SDL_MouseInit(void) { SDL_Mouse *mouse = SDL_GetMouse(); + SDL_zerop(mouse); + SDL_AddHintCallback(SDL_HINT_MOUSE_NORMAL_SPEED_SCALE, SDL_MouseNormalSpeedScaleChanged, mouse); @@ -587,8 +589,6 @@ SDL_MouseQuit(void) SDL_free(mouse->clickstate); } - SDL_zerop(mouse); - SDL_DelHintCallback(SDL_HINT_MOUSE_NORMAL_SPEED_SCALE, SDL_MouseNormalSpeedScaleChanged, mouse); From 02af3b001d9968205b255f896e0ab535111d639b Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 12 Oct 2017 13:44:28 -0700 Subject: [PATCH 61/95] Added functions to query and set the SDL memory allocation functions: SDL_GetMemoryFunctions() SDL_SetMemoryFunctions() SDL_GetNumAllocations() --- CMakeLists.txt | 4 +- VisualC/SDLtest/SDLtest.vcxproj | 3 +- WhatsNew.txt | 4 + .../SDL2test.xcodeproj/project.pbxproj | 8 + .../SDLTest/SDLTest.xcodeproj/project.pbxproj | 4 + configure | 15 +- configure.in | 5 +- include/SDL_config.h.cmake | 2 +- include/SDL_config.h.in | 2 +- include/SDL_config_android.h | 2 +- include/SDL_config_iphoneos.h | 2 +- include/SDL_config_macosx.h | 2 +- include/SDL_config_pandora.h | 1 - include/SDL_config_psp.h | 1 - include/SDL_config_wiz.h | 1 - include/SDL_stdinc.h | 31 ++++ include/SDL_test.h | 13 +- include/SDL_test_crc32.h | 2 +- include/SDL_test_memory.h | 63 +++++++ src/dynapi/SDL_dynapi_overrides.h | 3 + src/dynapi/SDL_dynapi_procs.h | 3 + src/stdlib/SDL_malloc.c | 172 ++++++++++++++---- src/stdlib/SDL_string.c | 4 - src/test/SDL_test_common.c | 26 ++- src/test/SDL_test_crc32.c | 2 - 25 files changed, 309 insertions(+), 66 deletions(-) create mode 100644 include/SDL_test_memory.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 1a36967efa..4af51987e2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -653,7 +653,7 @@ if(LIBC) check_include_file(sys/types.h HAVE_SYS_TYPES_H) foreach(_HEADER stdio.h stdlib.h stddef.h stdarg.h malloc.h memory.h string.h limits.h - strings.h wchar.h inttypes.h stdint.h ctype.h math.h iconv.h signal.h) + strings.h wchar.h inttypes.h stdint.h ctype.h math.h iconv.h signal.h libunwind.h) string(TOUPPER "HAVE_${_HEADER}" _UPPER) string(REPLACE "." "_" _HAVE_H ${_UPPER}) check_include_file("${_HEADER}" ${_HAVE_H}) @@ -669,7 +669,7 @@ if(LIBC) foreach(_FN strtod malloc calloc realloc free getenv setenv putenv unsetenv qsort abs bcopy memset memcpy memmove memcmp strlen strlcpy strlcat - strdup _strrev _strupr _strlwr strchr strrchr strstr itoa _ltoa + _strrev _strupr _strlwr strchr strrchr strstr itoa _ltoa _uitoa _ultoa strtol strtoul _i64toa _ui64toa strtoll strtoull atoi atof strcmp strncmp _stricmp strcasecmp _strnicmp strncasecmp vsscanf vsnprintf fopen64 fseeko fseeko64 sigaction setjmp diff --git a/VisualC/SDLtest/SDLtest.vcxproj b/VisualC/SDLtest/SDLtest.vcxproj index 6190a7dfa7..e2e39f935f 100644 --- a/VisualC/SDLtest/SDLtest.vcxproj +++ b/VisualC/SDLtest/SDLtest.vcxproj @@ -164,9 +164,10 @@ + - \ No newline at end of file + diff --git a/WhatsNew.txt b/WhatsNew.txt index 9e845f5cd4..04eeaad710 100644 --- a/WhatsNew.txt +++ b/WhatsNew.txt @@ -6,6 +6,10 @@ This is a list of major changes in SDL's version history. --------------------------------------------------------------------------- General: +* Added functions to query and set the SDL memory allocation functions: + SDL_GetMemoryFunctions() + SDL_SetMemoryFunctions() + SDL_GetNumAllocations() * Added locking functions for multi-threaded access to the joystick and game controller APIs: SDL_LockJoysticks() SDL_UnlockJoysticks() diff --git a/Xcode-iOS/SDLtest/SDL2test.xcodeproj/project.pbxproj b/Xcode-iOS/SDLtest/SDL2test.xcodeproj/project.pbxproj index 0d4fce7e93..99afeb1ee0 100644 --- a/Xcode-iOS/SDLtest/SDL2test.xcodeproj/project.pbxproj +++ b/Xcode-iOS/SDLtest/SDL2test.xcodeproj/project.pbxproj @@ -21,6 +21,8 @@ AA1EE46D176059AB0029C7A5 /* SDL_test_log.c in Sources */ = {isa = PBXBuildFile; fileRef = AA1EE45F176059AB0029C7A5 /* SDL_test_log.c */; }; AA1EE46E176059AB0029C7A5 /* SDL_test_md5.c in Sources */ = {isa = PBXBuildFile; fileRef = AA1EE460176059AB0029C7A5 /* SDL_test_md5.c */; }; AA1EE46F176059AB0029C7A5 /* SDL_test_random.c in Sources */ = {isa = PBXBuildFile; fileRef = AA1EE461176059AB0029C7A5 /* SDL_test_random.c */; }; + AAF030011F9009B100B9A9FB /* SDL_test_memory.c in Sources */ = {isa = PBXBuildFile; fileRef = AAF02FFF1F9009B100B9A9FB /* SDL_test_memory.c */; }; + AAF030021F9009B100B9A9FB /* SDL_test_assert.c in Sources */ = {isa = PBXBuildFile; fileRef = AAF030001F9009B100B9A9FB /* SDL_test_assert.c */; }; FA3D99011BC4E5BC002C96C8 /* SDL_test_common.c in Sources */ = {isa = PBXBuildFile; fileRef = AA1EE454176059AB0029C7A5 /* SDL_test_common.c */; }; FA3D99021BC4E5BC002C96C8 /* SDL_test_compare.c in Sources */ = {isa = PBXBuildFile; fileRef = AA1EE455176059AB0029C7A5 /* SDL_test_compare.c */; }; FA3D99031BC4E5BC002C96C8 /* SDL_test_crc32.c in Sources */ = {isa = PBXBuildFile; fileRef = AA1EE456176059AB0029C7A5 /* SDL_test_crc32.c */; }; @@ -65,6 +67,8 @@ AA1EE45F176059AB0029C7A5 /* SDL_test_log.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SDL_test_log.c; path = ../../src/test/SDL_test_log.c; sourceTree = ""; }; AA1EE460176059AB0029C7A5 /* SDL_test_md5.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SDL_test_md5.c; path = ../../src/test/SDL_test_md5.c; sourceTree = ""; }; AA1EE461176059AB0029C7A5 /* SDL_test_random.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SDL_test_random.c; path = ../../src/test/SDL_test_random.c; sourceTree = ""; }; + AAF02FFF1F9009B100B9A9FB /* SDL_test_memory.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SDL_test_memory.c; path = ../../src/test/SDL_test_memory.c; sourceTree = ""; }; + AAF030001F9009B100B9A9FB /* SDL_test_assert.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SDL_test_assert.c; path = ../../src/test/SDL_test_assert.c; sourceTree = ""; }; FA3D98F81BC4E5A2002C96C8 /* libSDL2test-TV.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libSDL2test-TV.a"; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ @@ -106,6 +110,7 @@ AA1EE453176059770029C7A5 /* Library Source */ = { isa = PBXGroup; children = ( + AAF030001F9009B100B9A9FB /* SDL_test_assert.c */, AA1EE454176059AB0029C7A5 /* SDL_test_common.c */, AA1EE455176059AB0029C7A5 /* SDL_test_compare.c */, AA1EE456176059AB0029C7A5 /* SDL_test_crc32.c */, @@ -119,6 +124,7 @@ AA1EE45E176059AB0029C7A5 /* SDL_test_imagePrimitivesBlend.c */, AA1EE45F176059AB0029C7A5 /* SDL_test_log.c */, AA1EE460176059AB0029C7A5 /* SDL_test_md5.c */, + AAF02FFF1F9009B100B9A9FB /* SDL_test_memory.c */, AA1EE461176059AB0029C7A5 /* SDL_test_random.c */, ); name = "Library Source"; @@ -213,12 +219,14 @@ AA1EE464176059AB0029C7A5 /* SDL_test_crc32.c in Sources */, AA1EE465176059AB0029C7A5 /* SDL_test_font.c in Sources */, AA1EE466176059AB0029C7A5 /* SDL_test_fuzzer.c in Sources */, + AAF030021F9009B100B9A9FB /* SDL_test_assert.c in Sources */, AA1EE467176059AB0029C7A5 /* SDL_test_harness.c in Sources */, AA1EE468176059AB0029C7A5 /* SDL_test_imageBlit.c in Sources */, AA1EE469176059AB0029C7A5 /* SDL_test_imageBlitBlend.c in Sources */, AA1EE46A176059AB0029C7A5 /* SDL_test_imageFace.c in Sources */, AA1EE46B176059AB0029C7A5 /* SDL_test_imagePrimitives.c in Sources */, AA1EE46C176059AB0029C7A5 /* SDL_test_imagePrimitivesBlend.c in Sources */, + AAF030011F9009B100B9A9FB /* SDL_test_memory.c in Sources */, AA1EE46D176059AB0029C7A5 /* SDL_test_log.c in Sources */, AA1EE46E176059AB0029C7A5 /* SDL_test_md5.c in Sources */, AA1EE46F176059AB0029C7A5 /* SDL_test_random.c in Sources */, diff --git a/Xcode/SDLTest/SDLTest.xcodeproj/project.pbxproj b/Xcode/SDLTest/SDLTest.xcodeproj/project.pbxproj index 144d24ca5e..cff071c7b7 100755 --- a/Xcode/SDLTest/SDLTest.xcodeproj/project.pbxproj +++ b/Xcode/SDLTest/SDLTest.xcodeproj/project.pbxproj @@ -348,6 +348,7 @@ 00794EF009D23739003FC8A1 /* utf8.txt in CopyFiles */ = {isa = PBXBuildFile; fileRef = 00794E6309D20839003FC8A1 /* utf8.txt */; }; 00794EF709D237DE003FC8A1 /* moose.dat in CopyFiles */ = {isa = PBXBuildFile; fileRef = 00794E5E09D20839003FC8A1 /* moose.dat */; }; 453774A5120915E3002F0F45 /* testshape.c in Sources */ = {isa = PBXBuildFile; fileRef = 453774A4120915E3002F0F45 /* testshape.c */; }; + AAF02FFA1F90092700B9A9FB /* SDL_test_memory.c in Sources */ = {isa = PBXBuildFile; fileRef = AAF02FF41F90089800B9A9FB /* SDL_test_memory.c */; }; BBFC08C0164C6862003E6A99 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002F33A709CA188600EBEB88 /* Cocoa.framework */; }; BBFC08C1164C6862003E6A99 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863B10730545007319AE /* CoreAudio.framework */; }; BBFC08C2164C6862003E6A99 /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863C10730545007319AE /* ForceFeedback.framework */; }; @@ -1152,6 +1153,7 @@ 092D6D75FFB313BB7F000001 /* testlock.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = testlock.c; path = ../../test/testlock.c; sourceTree = SOURCE_ROOT; }; 4537749212091504002F0F45 /* testshape */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testshape; sourceTree = BUILT_PRODUCTS_DIR; }; 453774A4120915E3002F0F45 /* testshape.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = testshape.c; path = ../../test/testshape.c; sourceTree = SOURCE_ROOT; }; + AAF02FF41F90089800B9A9FB /* SDL_test_memory.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SDL_test_memory.c; path = ../../src/test/SDL_test_memory.c; sourceTree = ""; }; BBFC088E164C6820003E6A99 /* testgamecontroller.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = testgamecontroller.c; path = ../../test/testgamecontroller.c; sourceTree = ""; }; BBFC08CD164C6862003E6A99 /* testgamecontroller */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testgamecontroller; sourceTree = BUILT_PRODUCTS_DIR; }; BEC566B60761D90300A33029 /* checkkeys */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = checkkeys; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -2212,6 +2214,7 @@ DB166D8F16A1D1A500A1396C /* SDL_test_imagePrimitivesBlend.c */, DB166D9016A1D1A500A1396C /* SDL_test_log.c */, DB166D9116A1D1A500A1396C /* SDL_test_md5.c */, + AAF02FF41F90089800B9A9FB /* SDL_test_memory.c */, DB166D9216A1D1A500A1396C /* SDL_test_random.c */, ); name = SDL_Test; @@ -3393,6 +3396,7 @@ DB166D9E16A1D1A500A1396C /* SDL_test_imagePrimitivesBlend.c in Sources */, DB166D9F16A1D1A500A1396C /* SDL_test_log.c in Sources */, DB166DA016A1D1A500A1396C /* SDL_test_md5.c in Sources */, + AAF02FFA1F90092700B9A9FB /* SDL_test_memory.c in Sources */, DB166DA116A1D1A500A1396C /* SDL_test_random.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/configure b/configure index fc0d3466cd..b622085ed5 100755 --- a/configure +++ b/configure @@ -16635,7 +16635,7 @@ fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi - for ac_func in malloc calloc realloc free getenv setenv putenv unsetenv qsort abs bcopy memset memcpy memmove wcslen wcscmp strlen strlcpy strlcat strdup _strrev _strupr _strlwr strchr strrchr strstr itoa _ltoa _uitoa _ultoa strtol strtoul _i64toa _ui64toa strtoll strtoull atoi atof strcmp strncmp _stricmp strcasecmp _strnicmp strncasecmp vsscanf vsnprintf fopen64 fseeko fseeko64 sigaction setjmp nanosleep sysconf sysctlbyname getauxval poll + for ac_func in malloc calloc realloc free getenv setenv putenv unsetenv qsort abs bcopy memset memcpy memmove wcslen wcscmp strlen strlcpy strlcat _strrev _strupr _strlwr strchr strrchr strstr itoa _ltoa _uitoa _ultoa strtol strtoul _i64toa _ui64toa strtoll strtoull atoi atof strcmp strncmp _stricmp strcasecmp _strnicmp strncasecmp vsscanf vsnprintf fopen64 fseeko fseeko64 sigaction setjmp nanosleep sysconf sysctlbyname getauxval poll do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" @@ -16761,6 +16761,19 @@ $as_echo "#define HAVE_SA_SIGACTION 1" >>confdefs.h fi + + for ac_header in libunwind.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "libunwind.h" "ac_cv_header_libunwind_h" "$ac_includes_default" +if test "x$ac_cv_header_libunwind_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBUNWIND_H 1 +_ACEOF + +fi + +done + fi diff --git a/configure.in b/configure.in index a4b88f9d16..5ac2130844 100644 --- a/configure.in +++ b/configure.in @@ -268,7 +268,7 @@ if test x$enable_libc = xyes; then AC_DEFINE(HAVE_MPROTECT, 1, [ ]) ]), ) - AC_CHECK_FUNCS(malloc calloc realloc free getenv setenv putenv unsetenv qsort abs bcopy memset memcpy memmove wcslen wcscmp strlen strlcpy strlcat strdup _strrev _strupr _strlwr strchr strrchr strstr itoa _ltoa _uitoa _ultoa strtol strtoul _i64toa _ui64toa strtoll strtoull atoi atof strcmp strncmp _stricmp strcasecmp _strnicmp strncasecmp vsscanf vsnprintf fopen64 fseeko fseeko64 sigaction setjmp nanosleep sysconf sysctlbyname getauxval poll) + AC_CHECK_FUNCS(malloc calloc realloc free getenv setenv putenv unsetenv qsort abs bcopy memset memcpy memmove wcslen wcscmp strlen strlcpy strlcat _strrev _strupr _strlwr strchr strrchr strstr itoa _ltoa _uitoa _ultoa strtol strtoul _i64toa _ui64toa strtoll strtoull atoi atof strcmp strncmp _stricmp strcasecmp _strnicmp strncasecmp vsscanf vsnprintf fopen64 fseeko fseeko64 sigaction setjmp nanosleep sysconf sysctlbyname getauxval poll) AC_CHECK_LIB(m, pow, [LIBS="$LIBS -lm"; EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lm"]) AC_CHECK_FUNCS(atan atan2 acos asin ceil copysign cos cosf fabs floor log pow scalbn sin sinf sqrt sqrtf tan tanf) @@ -277,6 +277,9 @@ if test x$enable_libc = xyes; then AC_CHECK_FUNCS(iconv) AC_CHECK_MEMBER(struct sigaction.sa_sigaction,[AC_DEFINE([HAVE_SA_SIGACTION], 1, [ ])], ,[#include ]) + + dnl Check for additional non-standard headers + AC_CHECK_HEADERS(libunwind.h) fi dnl AC_CHECK_SIZEOF(void*) diff --git a/include/SDL_config.h.cmake b/include/SDL_config.h.cmake index 9befa422f1..9b20398d0d 100644 --- a/include/SDL_config.h.cmake +++ b/include/SDL_config.h.cmake @@ -72,6 +72,7 @@ #cmakedefine HAVE_SYS_TYPES_H 1 #cmakedefine HAVE_WCHAR_H 1 #cmakedefine HAVE_PTHREAD_NP_H 1 +#cmakedefine HAVE_LIBUNWIND_H 1 /* C library functions */ #cmakedefine HAVE_MALLOC 1 @@ -99,7 +100,6 @@ #cmakedefine HAVE_STRLEN 1 #cmakedefine HAVE_STRLCPY 1 #cmakedefine HAVE_STRLCAT 1 -#cmakedefine HAVE_STRDUP 1 #cmakedefine HAVE__STRREV 1 #cmakedefine HAVE__STRUPR 1 #cmakedefine HAVE__STRLWR 1 diff --git a/include/SDL_config.h.in b/include/SDL_config.h.in index 988d3d93d0..a28e83ff07 100644 --- a/include/SDL_config.h.in +++ b/include/SDL_config.h.in @@ -75,6 +75,7 @@ #undef HAVE_SYS_TYPES_H #undef HAVE_WCHAR_H #undef HAVE_PTHREAD_NP_H +#undef HAVE_LIBUNWIND_H /* C library functions */ #undef HAVE_MALLOC @@ -102,7 +103,6 @@ #undef HAVE_STRLEN #undef HAVE_STRLCPY #undef HAVE_STRLCAT -#undef HAVE_STRDUP #undef HAVE__STRREV #undef HAVE__STRUPR #undef HAVE__STRLWR diff --git a/include/SDL_config_android.h b/include/SDL_config_android.h index c3169e557c..46638193d7 100644 --- a/include/SDL_config_android.h +++ b/include/SDL_config_android.h @@ -46,6 +46,7 @@ #define HAVE_STDIO_H 1 #define HAVE_STRING_H 1 #define HAVE_SYS_TYPES_H 1 +#define HAVE_LIBUNWIND_H 1 /* C library functions */ #define HAVE_MALLOC 1 @@ -68,7 +69,6 @@ #define HAVE_STRLEN 1 #define HAVE_STRLCPY 1 #define HAVE_STRLCAT 1 -#define HAVE_STRDUP 1 #define HAVE_STRCHR 1 #define HAVE_STRRCHR 1 #define HAVE_STRSTR 1 diff --git a/include/SDL_config_iphoneos.h b/include/SDL_config_iphoneos.h index 94ab6933c4..38dcd9a77d 100644 --- a/include/SDL_config_iphoneos.h +++ b/include/SDL_config_iphoneos.h @@ -44,6 +44,7 @@ #define HAVE_STDIO_H 1 #define HAVE_STRING_H 1 #define HAVE_SYS_TYPES_H 1 +#define HAVE_LIBUNWIND_H 1 /* C library functions */ #define HAVE_MALLOC 1 @@ -66,7 +67,6 @@ #define HAVE_STRLEN 1 #define HAVE_STRLCPY 1 #define HAVE_STRLCAT 1 -#define HAVE_STRDUP 1 #define HAVE_STRCHR 1 #define HAVE_STRRCHR 1 #define HAVE_STRSTR 1 diff --git a/include/SDL_config_macosx.h b/include/SDL_config_macosx.h index 67f879a492..f75507894e 100644 --- a/include/SDL_config_macosx.h +++ b/include/SDL_config_macosx.h @@ -49,6 +49,7 @@ #define HAVE_STDIO_H 1 #define HAVE_STRING_H 1 #define HAVE_SYS_TYPES_H 1 +#define HAVE_LIBUNWIND_H 1 /* C library functions */ #define HAVE_MALLOC 1 @@ -70,7 +71,6 @@ #define HAVE_STRLEN 1 #define HAVE_STRLCPY 1 #define HAVE_STRLCAT 1 -#define HAVE_STRDUP 1 #define HAVE_STRCHR 1 #define HAVE_STRRCHR 1 #define HAVE_STRSTR 1 diff --git a/include/SDL_config_pandora.h b/include/SDL_config_pandora.h index f6f52fc11e..f421c74a88 100644 --- a/include/SDL_config_pandora.h +++ b/include/SDL_config_pandora.h @@ -70,7 +70,6 @@ #define HAVE_MEMCPY 1 #define HAVE_MEMMOVE 1 #define HAVE_STRLEN 1 -#define HAVE_STRDUP 1 #define HAVE_STRCHR 1 #define HAVE_STRRCHR 1 #define HAVE_STRSTR 1 diff --git a/include/SDL_config_psp.h b/include/SDL_config_psp.h index 0e61979066..b76cf7de22 100644 --- a/include/SDL_config_psp.h +++ b/include/SDL_config_psp.h @@ -66,7 +66,6 @@ #define HAVE_STRLEN 1 #define HAVE_STRLCPY 1 #define HAVE_STRLCAT 1 -#define HAVE_STRDUP 1 #define HAVE_STRCHR 1 #define HAVE_STRRCHR 1 #define HAVE_STRSTR 1 diff --git a/include/SDL_config_wiz.h b/include/SDL_config_wiz.h index 3afd8d8af4..0c8f02d8b7 100644 --- a/include/SDL_config_wiz.h +++ b/include/SDL_config_wiz.h @@ -64,7 +64,6 @@ #define HAVE_MEMCPY 1 #define HAVE_MEMMOVE 1 #define HAVE_STRLEN 1 -#define HAVE_STRDUP 1 #define HAVE_STRCHR 1 #define HAVE_STRRCHR 1 #define HAVE_STRSTR 1 diff --git a/include/SDL_stdinc.h b/include/SDL_stdinc.h index 546544f10d..16100b8b87 100644 --- a/include/SDL_stdinc.h +++ b/include/SDL_stdinc.h @@ -347,6 +347,37 @@ extern DECLSPEC void *SDLCALL SDL_calloc(size_t nmemb, size_t size); extern DECLSPEC void *SDLCALL SDL_realloc(void *mem, size_t size); extern DECLSPEC void SDLCALL SDL_free(void *mem); +typedef void *(SDLCALL *SDL_malloc_func)(size_t size); +typedef void *(SDLCALL *SDL_calloc_func)(size_t nmemb, size_t size); +typedef void *(SDLCALL *SDL_realloc_func)(void *mem, size_t size); +typedef void (SDLCALL *SDL_free_func)(void *mem); + +/** + * \brief Get the current set of SDL memory functions + */ +extern DECLSPEC void SDLCALL SDL_GetMemoryFunctions(SDL_malloc_func *malloc_func, + SDL_calloc_func *calloc_func, + SDL_realloc_func *realloc_func, + SDL_free_func *free_func); + +/** + * \brief Replace SDL's memory allocation functions with a custom set + * + * \note If you are replacing SDL's memory functions, you should call + * SDL_GetNumAllocations() and be very careful if it returns non-zero. + * That means that your free function will be called with memory + * allocated by the previous memory allocation functions. + */ +extern DECLSPEC int SDLCALL SDL_SetMemoryFunctions(SDL_malloc_func malloc_func, + SDL_calloc_func calloc_func, + SDL_realloc_func realloc_func, + SDL_free_func free_func); + +/** + * \brief Get the number of outstanding (unfreed) allocations + */ +extern DECLSPEC int SDLCALL SDL_GetNumAllocations(); + extern DECLSPEC char *SDLCALL SDL_getenv(const char *name); extern DECLSPEC int SDLCALL SDL_setenv(const char *name, const char *value, int overwrite); diff --git a/include/SDL_test.h b/include/SDL_test.h index 62c1be37bf..f55afcb022 100644 --- a/include/SDL_test.h +++ b/include/SDL_test.h @@ -31,17 +31,18 @@ #define SDL_test_h_ #include "SDL.h" +#include "SDL_test_assert.h" #include "SDL_test_common.h" +#include "SDL_test_compare.h" +#include "SDL_test_crc32.h" #include "SDL_test_font.h" -#include "SDL_test_random.h" #include "SDL_test_fuzzer.h" -#include "SDL_test_crc32.h" -#include "SDL_test_md5.h" -#include "SDL_test_log.h" -#include "SDL_test_assert.h" #include "SDL_test_harness.h" #include "SDL_test_images.h" -#include "SDL_test_compare.h" +#include "SDL_test_log.h" +#include "SDL_test_md5.h" +#include "SDL_test_memory.h" +#include "SDL_test_random.h" #include "begin_code.h" /* Set up for C function definitions, even when using C++ */ diff --git a/include/SDL_test_crc32.h b/include/SDL_test_crc32.h index 65aa64edb3..add480c349 100644 --- a/include/SDL_test_crc32.h +++ b/include/SDL_test_crc32.h @@ -93,7 +93,7 @@ extern "C" { * \returns 0 for OK, -1 on error * */ -int SDLTest_crc32Calc(SDLTest_Crc32Context * crcContext, CrcUint8 *inBuf, CrcUint32 inLen, CrcUint32 *crc32); +int SDLTest_Crc32Calc(SDLTest_Crc32Context * crcContext, CrcUint8 *inBuf, CrcUint32 inLen, CrcUint32 *crc32); /* Same routine broken down into three steps */ int SDLTest_Crc32CalcStart(SDLTest_Crc32Context * crcContext, CrcUint32 *crc32); diff --git a/include/SDL_test_memory.h b/include/SDL_test_memory.h new file mode 100644 index 0000000000..43b67f521b --- /dev/null +++ b/include/SDL_test_memory.h @@ -0,0 +1,63 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2017 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. +*/ + +/** + * \file SDL_test_memory.h + * + * Include file for SDL test framework. + * + * This code is a part of the SDL2_test library, not the main SDL library. + */ + +#ifndef SDL_test_memory_h_ +#define SDL_test_memory_h_ + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * \brief Start tracking SDL memory allocations + * + * \note This should be called before any other SDL functions for complete tracking coverage + */ +int SDLTest_TrackAllocations(); + +/** + * \brief Print a log of any outstanding allocations + * + * \note This can be called after SDL_Quit() + */ +void SDLTest_LogAllocations(); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_test_memory_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h index 3ef56d23af..a079e92a3f 100644 --- a/src/dynapi/SDL_dynapi_overrides.h +++ b/src/dynapi/SDL_dynapi_overrides.h @@ -637,3 +637,6 @@ #define SDL_Vulkan_GetDrawableSize SDL_Vulkan_GetDrawableSize_REAL #define SDL_LockJoysticks SDL_LockJoysticks_REAL #define SDL_UnlockJoysticks SDL_UnlockJoysticks_REAL +#define SDL_GetMemoryFunctions SDL_GetMemoryFunctions_REAL +#define SDL_SetMemoryFunctions SDL_SetMemoryFunctions_REAL +#define SDL_GetNumAllocations SDL_GetNumAllocations_REAL diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h index 730fbcc327..237c54aac5 100644 --- a/src/dynapi/SDL_dynapi_procs.h +++ b/src/dynapi/SDL_dynapi_procs.h @@ -671,3 +671,6 @@ SDL_DYNAPI_PROC(SDL_bool,SDL_Vulkan_CreateSurface,(SDL_Window *a, VkInstance b, SDL_DYNAPI_PROC(void,SDL_Vulkan_GetDrawableSize,(SDL_Window *a, int *b, int *c),(a,b,c),) SDL_DYNAPI_PROC(void,SDL_LockJoysticks,(void),(),) SDL_DYNAPI_PROC(void,SDL_UnlockJoysticks,(void),(),) +SDL_DYNAPI_PROC(void,SDL_GetMemoryFunctions,(SDL_malloc_func *a, SDL_calloc_func *b, SDL_realloc_func *c, SDL_free_func *d),(a,b,c,d),) +SDL_DYNAPI_PROC(int,SDL_SetMemoryFunctions,(SDL_malloc_func a, SDL_calloc_func b, SDL_realloc_func c, SDL_free_func d),(a,b,c,d),return) +SDL_DYNAPI_PROC(int,SDL_GetNumAllocations,(void),(),return) diff --git a/src/stdlib/SDL_malloc.c b/src/stdlib/SDL_malloc.c index de7f13a945..ac13373d0b 100644 --- a/src/stdlib/SDL_malloc.c +++ b/src/stdlib/SDL_malloc.c @@ -26,39 +26,11 @@ #include "../SDL_internal.h" /* This file contains portable memory management functions for SDL */ - #include "SDL_stdinc.h" +#include "SDL_atomic.h" +#include "SDL_error.h" -#if defined(HAVE_MALLOC) - -void *SDL_malloc(size_t size) -{ - if (!size) { - return malloc(1); - } - return malloc(size); -} - -void *SDL_calloc(size_t nmemb, size_t size) -{ - if (!size || !nmemb) { - return calloc(1,1); - } - return calloc(nmemb, size); -} - -void *SDL_realloc(void *ptr, size_t size) -{ - return realloc(ptr, size); -} - -void SDL_free(void *ptr) -{ - free(ptr); -} - -#else /* the rest of this is a LOT of tapdancing to implement malloc. :) */ - +#ifndef HAVE_MALLOC #define LACKS_SYS_TYPES_H #define LACKS_STDIO_H #define LACKS_STRINGS_H @@ -66,6 +38,7 @@ void SDL_free(void *ptr) #define LACKS_STDLIB_H #define ABORT #define USE_LOCKS 1 +#define USE_DL_PREFIX /* This is a version (aka dlmalloc) of malloc/free/realloc written by @@ -642,12 +615,12 @@ DEFAULT_MMAP_THRESHOLD default: 256K #define MALLINFO_FIELD_TYPE size_t #endif /* MALLINFO_FIELD_TYPE */ +#ifndef memset #define memset SDL_memset +#endif +#ifndef memcpy #define memcpy SDL_memcpy -#define malloc SDL_malloc -#define calloc SDL_calloc -#define realloc SDL_realloc -#define free SDL_free +#endif /* mallopt tuning options. SVID/XPG defines four standard parameter @@ -5271,4 +5244,133 @@ mspace_mallopt(int param_number, int value) #endif /* !HAVE_MALLOC */ +#ifdef HAVE_MALLOC +#define real_malloc malloc +#define real_calloc calloc +#define real_realloc realloc +#define real_free free +#else +#define real_malloc dlmalloc +#define real_calloc dlcalloc +#define real_realloc dlrealloc +#define real_free dlfree +#endif + +/* Memory functions used by SDL that can be replaced by the application */ +static struct +{ + SDL_malloc_func malloc_func; + SDL_calloc_func calloc_func; + SDL_realloc_func realloc_func; + SDL_free_func free_func; + SDL_atomic_t num_allocations; +} s_mem = { + real_malloc, real_calloc, real_realloc, real_free, { 0 } +}; + +void SDL_GetMemoryFunctions(SDL_malloc_func *malloc_func, + SDL_calloc_func *calloc_func, + SDL_realloc_func *realloc_func, + SDL_free_func *free_func) +{ + if (malloc_func) { + *malloc_func = s_mem.malloc_func; + } + if (calloc_func) { + *calloc_func = s_mem.calloc_func; + } + if (realloc_func) { + *realloc_func = s_mem.realloc_func; + } + if (free_func) { + *free_func = s_mem.free_func; + } +} + +int SDL_SetMemoryFunctions(SDL_malloc_func malloc_func, + SDL_calloc_func calloc_func, + SDL_realloc_func realloc_func, + SDL_free_func free_func) +{ + if (!malloc_func) { + return SDL_InvalidParamError("malloc_func"); + } + if (!calloc_func) { + return SDL_InvalidParamError("calloc_func"); + } + if (!realloc_func) { + return SDL_InvalidParamError("realloc_func"); + } + if (!free_func) { + return SDL_InvalidParamError("free_func"); + } + + s_mem.malloc_func = malloc_func; + s_mem.calloc_func = calloc_func; + s_mem.realloc_func = realloc_func; + s_mem.free_func = free_func; + return 0; +} + +int SDL_GetNumAllocations() +{ + return SDL_AtomicGet(&s_mem.num_allocations); +} + +void *SDL_malloc(size_t size) +{ + void *mem; + + if (!size) { + size = 1; + } + + mem = s_mem.malloc_func(size); + if (mem) { + SDL_AtomicIncRef(&s_mem.num_allocations); + } + return mem; +} + +void *SDL_calloc(size_t nmemb, size_t size) +{ + void *mem; + + if (!nmemb || !size) { + nmemb = 1; + size = 1; + } + + mem = s_mem.calloc_func(nmemb, size); + if (mem) { + SDL_AtomicIncRef(&s_mem.num_allocations); + } + return mem; +} + +void *SDL_realloc(void *ptr, size_t size) +{ + void *mem; + + if (!ptr && !size) { + size = 1; + } + + mem = s_mem.realloc_func(ptr, size); + if (mem && !ptr) { + SDL_AtomicIncRef(&s_mem.num_allocations); + } + return mem; +} + +void SDL_free(void *ptr) +{ + if (!ptr) { + return; + } + + s_mem.free_func(ptr); + SDL_AtomicDecRef(&s_mem.num_allocations); +} + /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/stdlib/SDL_string.c b/src/stdlib/SDL_string.c index 1b6c39304e..ae5fef214d 100644 --- a/src/stdlib/SDL_string.c +++ b/src/stdlib/SDL_string.c @@ -561,16 +561,12 @@ SDL_strlcat(SDL_INOUT_Z_CAP(maxlen) char *dst, const char *src, size_t maxlen) char * SDL_strdup(const char *string) { -#if defined(HAVE_STRDUP) - return strdup(string); -#else size_t len = SDL_strlen(string) + 1; char *newstr = SDL_malloc(len); if (newstr) { SDL_strlcpy(newstr, string, len); } return newstr; -#endif /* HAVE_STRDUP */ } char * diff --git a/src/test/SDL_test_common.c b/src/test/SDL_test_common.c index 780993c5b9..f288d2330b 100644 --- a/src/test/SDL_test_common.c +++ b/src/test/SDL_test_common.c @@ -47,7 +47,18 @@ static void SDL_snprintfcat(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, SDL SDLTest_CommonState * SDLTest_CommonCreateState(char **argv, Uint32 flags) { - SDLTest_CommonState *state = (SDLTest_CommonState *)SDL_calloc(1, sizeof(*state)); + int i; + SDLTest_CommonState *state; + + /* Do this first so we catch all allocations */ + for (i = 1; argv[i]; ++i) { + if (SDL_strcasecmp(argv[i], "--trackmem") == 0) { + SDLTest_TrackAllocations(); + break; + } + } + + state = (SDLTest_CommonState *)SDL_calloc(1, sizeof(*state)); if (!state) { SDL_OutOfMemory(); return NULL; @@ -447,6 +458,10 @@ SDLTest_CommonArg(SDLTest_CommonState * state, int index) state->audiospec.samples = (Uint16) SDL_atoi(argv[index]); return 2; } + if (SDL_strcasecmp(argv[index], "--trackmem") == 0) { + /* Already handled in SDLTest_CommonCreateState() */ + return 1; + } if ((SDL_strcasecmp(argv[index], "-h") == 0) || (SDL_strcasecmp(argv[index], "--help") == 0)) { /* Print the usage message */ @@ -464,13 +479,13 @@ SDLTest_CommonUsage(SDLTest_CommonState * state) { switch (state->flags & (SDL_INIT_VIDEO | SDL_INIT_AUDIO)) { case SDL_INIT_VIDEO: - return VIDEO_USAGE; + return "[--trackmem] " VIDEO_USAGE; case SDL_INIT_AUDIO: - return AUDIO_USAGE; + return "[--trackmem] " AUDIO_USAGE; case (SDL_INIT_VIDEO | SDL_INIT_AUDIO): - return VIDEO_USAGE " " AUDIO_USAGE; + return "[--trackmem] " VIDEO_USAGE " " AUDIO_USAGE; default: - return ""; + return "[--trackmem]"; } } @@ -1762,6 +1777,7 @@ SDLTest_CommonQuit(SDLTest_CommonState * state) } SDL_free(state); SDL_Quit(); + SDLTest_LogAllocations(); } /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/test/SDL_test_crc32.c b/src/test/SDL_test_crc32.c index a8878eaa2a..867f7c611a 100644 --- a/src/test/SDL_test_crc32.c +++ b/src/test/SDL_test_crc32.c @@ -69,7 +69,6 @@ int SDLTest_Crc32Init(SDLTest_Crc32Context *crcContext) } /* Complete CRC32 calculation on a memory block */ -/* un-used int SDLTest_Crc32Calc(SDLTest_Crc32Context * crcContext, CrcUint8 *inBuf, CrcUint32 inLen, CrcUint32 *crc32) { if (SDLTest_Crc32CalcStart(crcContext,crc32)) { @@ -86,7 +85,6 @@ int SDLTest_Crc32Calc(SDLTest_Crc32Context * crcContext, CrcUint8 *inBuf, CrcUin return 0; } -*/ /* Start crc calculation */ From f58ff532ee142627664b3239c6fcaa162b6e8be8 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 12 Oct 2017 13:55:35 -0700 Subject: [PATCH 62/95] Fixed compiler warning --- src/audio/SDL_audiocvt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/audio/SDL_audiocvt.c b/src/audio/SDL_audiocvt.c index 4c8db0fc5a..3f505d7fd8 100644 --- a/src/audio/SDL_audiocvt.c +++ b/src/audio/SDL_audiocvt.c @@ -515,14 +515,14 @@ SDL_ResampleAudio(const int chans, const int inrate, const int outrate, const int srcframe = srcindex - j; /* !!! FIXME: we can bubble this conditional out of here by doing a pre loop. */ const float insample = (srcframe < 0) ? lpadding[((paddinglen + srcframe) * chans) + chan] : inbuf[(srcframe * chans) + chan]; - outsample += (insample * (ResamplerFilter[filterindex1 + (j * RESAMPLER_SAMPLES_PER_ZERO_CROSSING)] + (interpolation1 * ResamplerFilterDifference[filterindex1 + (j * RESAMPLER_SAMPLES_PER_ZERO_CROSSING)]))); + outsample += (float)(insample * (ResamplerFilter[filterindex1 + (j * RESAMPLER_SAMPLES_PER_ZERO_CROSSING)] + (interpolation1 * ResamplerFilterDifference[filterindex1 + (j * RESAMPLER_SAMPLES_PER_ZERO_CROSSING)]))); } for (j = 0; (filterindex2 + (j * RESAMPLER_SAMPLES_PER_ZERO_CROSSING)) < RESAMPLER_FILTER_SIZE; j++) { const int srcframe = srcindex + 1 + j; /* !!! FIXME: we can bubble this conditional out of here by doing a post loop. */ const float insample = (srcframe >= inframes) ? rpadding[((srcframe - inframes) * chans) + chan] : inbuf[(srcframe * chans) + chan]; - outsample += (insample * (ResamplerFilter[filterindex2 + (j * RESAMPLER_SAMPLES_PER_ZERO_CROSSING)] + (interpolation2 * ResamplerFilterDifference[filterindex2 + (j * RESAMPLER_SAMPLES_PER_ZERO_CROSSING)]))); + outsample += (float)(insample * (ResamplerFilter[filterindex2 + (j * RESAMPLER_SAMPLES_PER_ZERO_CROSSING)] + (interpolation2 * ResamplerFilterDifference[filterindex2 + (j * RESAMPLER_SAMPLES_PER_ZERO_CROSSING)]))); } *(dst++) = outsample; } From dc3b4f987cf7f30933cc719fa608b4679224764e Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 12 Oct 2017 14:02:24 -0700 Subject: [PATCH 63/95] Fixed compiler warning --- src/stdlib/SDL_malloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stdlib/SDL_malloc.c b/src/stdlib/SDL_malloc.c index ac13373d0b..c2cb1f3a63 100644 --- a/src/stdlib/SDL_malloc.c +++ b/src/stdlib/SDL_malloc.c @@ -5370,7 +5370,7 @@ void SDL_free(void *ptr) } s_mem.free_func(ptr); - SDL_AtomicDecRef(&s_mem.num_allocations); + (void)SDL_AtomicDecRef(&s_mem.num_allocations); } /* vi: set ts=4 sw=4 expandtab: */ From 720f9791eb35dc6097b355f7eca728f4b130b38b Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 12 Oct 2017 14:20:17 -0700 Subject: [PATCH 64/95] Added missing file --- src/test/SDL_test_memory.c | 274 +++++++++++++++++++++++++++++++++++++ 1 file changed, 274 insertions(+) create mode 100644 src/test/SDL_test_memory.c diff --git a/src/test/SDL_test_memory.c b/src/test/SDL_test_memory.c new file mode 100644 index 0000000000..15395e889a --- /dev/null +++ b/src/test/SDL_test_memory.c @@ -0,0 +1,274 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2017 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. +*/ +#include "SDL_config.h" +#include "SDL_assert.h" +#include "SDL_stdinc.h" +#include "SDL_log.h" +#include "SDL_test_crc32.h" +#include "SDL_test_memory.h" + +#ifdef HAVE_LIBUNWIND_H +#include +#endif + +/* This is a simple tracking allocator to demonstrate the use of SDL's + memory allocation replacement functionality. + + It gets slow with large numbers of allocations and shouldn't be used + for production code. +*/ + +typedef struct SDL_tracked_allocation +{ + void *mem; + size_t size; + Uint64 stack[10]; + char stack_names[10][256]; + struct SDL_tracked_allocation *next; +} SDL_tracked_allocation; + +static SDLTest_Crc32Context s_crc32_context; +static SDL_malloc_func SDL_malloc_orig = NULL; +static SDL_calloc_func SDL_calloc_orig = NULL; +static SDL_realloc_func SDL_realloc_orig = NULL; +static SDL_free_func SDL_free_orig = NULL; +static int s_previous_allocations = 0; +static SDL_tracked_allocation *s_tracked_allocations[256]; + +static unsigned int get_allocation_bucket(void *mem) +{ + CrcUint32 crc_value; + unsigned int index; + SDLTest_Crc32Calc(&s_crc32_context, (CrcUint8 *)&mem, sizeof(mem), &crc_value); + index = (crc_value & (SDL_arraysize(s_tracked_allocations) - 1)); + return index; +} + +static SDL_bool SDL_IsAllocationTracked(void *mem) +{ + SDL_tracked_allocation *entry; + int index = get_allocation_bucket(mem); + for (entry = s_tracked_allocations[index]; entry; entry = entry->next) { + if (mem == entry->mem) { + return SDL_TRUE; + } + } + return SDL_FALSE; +} + +static void SDL_TrackAllocation(void *mem, size_t size) +{ + SDL_tracked_allocation *entry; + int index = get_allocation_bucket(mem); + + if (SDL_IsAllocationTracked(mem)) { + return; + } + entry = (SDL_tracked_allocation *)SDL_malloc_orig(sizeof(*entry)); + if (!entry) { + return; + } + entry->mem = mem; + entry->size = size; + + /* Generate the stack trace for the allocation */ + SDL_zero(entry->stack); +#ifdef HAVE_LIBUNWIND_H + { + int stack_index; + unw_cursor_t cursor; + unw_context_t context; + + unw_getcontext(&context); + unw_init_local(&cursor, &context); + + stack_index = 0; + while (unw_step(&cursor) > 0) { + unw_word_t offset, pc; + char sym[256]; + + unw_get_reg(&cursor, UNW_REG_IP, &pc); + entry->stack[stack_index] = pc; + + if (unw_get_proc_name(&cursor, sym, sizeof(sym), &offset) == 0) { + snprintf(entry->stack_names[stack_index], sizeof(entry->stack_names[stack_index]), "%s+0x%llx", sym, offset); + } + ++stack_index; + + if (stack_index == SDL_arraysize(entry->stack)) { + break; + } + } + } +#endif /* HAVE_LIBUNWIND_H */ + + entry->next = s_tracked_allocations[index]; + s_tracked_allocations[index] = entry; +} + +static void SDL_UntrackAllocation(void *mem) +{ + SDL_tracked_allocation *entry, *prev; + int index = get_allocation_bucket(mem); + + prev = NULL; + for (entry = s_tracked_allocations[index]; entry; entry = entry->next) { + if (mem == entry->mem) { + if (prev) { + prev->next = entry->next; + } else { + s_tracked_allocations[index] = entry->next; + } + SDL_free_orig(entry); + return; + } + prev = entry; + } +} + +static void *SDLTest_TrackedMalloc(size_t size) +{ + void *mem; + + mem = SDL_malloc_orig(size); + if (mem) { + SDL_TrackAllocation(mem, size); + } + return mem; +} + +static void *SDLTest_TrackedCalloc(size_t nmemb, size_t size) +{ + void *mem; + + mem = SDL_calloc_orig(nmemb, size); + if (mem) { + SDL_TrackAllocation(mem, nmemb * size); + } + return mem; +} + +static void *SDLTest_TrackedRealloc(void *ptr, size_t size) +{ + void *mem; + + SDL_assert(!ptr || SDL_IsAllocationTracked(ptr)); + mem = SDL_realloc_orig(ptr, size); + if (mem && mem != ptr) { + if (ptr) { + SDL_UntrackAllocation(ptr); + } + SDL_TrackAllocation(mem, size); + } + return mem; +} + +static void SDLTest_TrackedFree(void *ptr) +{ + if (!ptr) { + return; + } + + if (!s_previous_allocations) { + SDL_assert(SDL_IsAllocationTracked(ptr)); + } + SDL_UntrackAllocation(ptr); + SDL_free_orig(ptr); +} + +int SDLTest_TrackAllocations() +{ + if (SDL_malloc_orig) { + return 0; + } + + SDLTest_Crc32Init(&s_crc32_context); + + s_previous_allocations = SDL_GetNumAllocations(); + if (s_previous_allocations != 0) { + SDL_Log("SDLTest_TrackAllocations(): There are %d previous allocations, disabling free() validation", s_previous_allocations); + } + + SDL_GetMemoryFunctions(&SDL_malloc_orig, + &SDL_calloc_orig, + &SDL_realloc_orig, + &SDL_free_orig); + + SDL_SetMemoryFunctions(SDLTest_TrackedMalloc, + SDLTest_TrackedCalloc, + SDLTest_TrackedRealloc, + SDLTest_TrackedFree); + return 0; +} + +void SDLTest_LogAllocations() +{ + char *message = NULL; + size_t message_size = 0; + char line[128], *tmp; + SDL_tracked_allocation *entry; + int index, count, stack_index; + Uint64 total_allocated; + + if (!SDL_malloc_orig) { + return; + } + +#define ADD_LINE() \ + message_size += (SDL_strlen(line) + 1); \ + tmp = (char *)SDL_realloc_orig(message, message_size); \ + if (!tmp) { \ + return; \ + } \ + message = tmp; \ + SDL_strlcat(message, line, message_size) + + SDL_strlcpy(line, "Memory allocations:\n", sizeof(line)); + ADD_LINE(); + SDL_strlcpy(line, "Expect 2 allocations from within SDL_GetErrBuf()\n", sizeof(line)); + ADD_LINE(); + + count = 0; + total_allocated = 0; + for (index = 0; index < SDL_arraysize(s_tracked_allocations); ++index) { + for (entry = s_tracked_allocations[index]; entry; entry = entry->next) { + SDL_snprintf(line, sizeof(line), "Allocation %d: %lu bytes\n", count, entry->size); + ADD_LINE(); + /* Start at stack index 1 to skip our tracking functions */ + for (stack_index = 1; stack_index < SDL_arraysize(entry->stack); ++stack_index) { + if (!entry->stack[stack_index]) { + break; + } + SDL_snprintf(line, sizeof(line), "\t0x%llx: %s\n", entry->stack[stack_index], entry->stack_names[stack_index]); + ADD_LINE(); + } + total_allocated += entry->size; + ++count; + } + } + SDL_snprintf(line, sizeof(line), "Total: %.2f Kb in %d allocations\n", (float)total_allocated / 1024, count); + ADD_LINE(); +#undef ADD_LINE + + SDL_Log("%s", message); +} + +/* vi: set ts=4 sw=4 expandtab: */ From 6add103b484e4cdb168acfc9b56f38bbc57eb7d7 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 12 Oct 2017 14:21:21 -0700 Subject: [PATCH 65/95] Android doesn't have libunwind.h in API 16 --- include/SDL_config_android.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/SDL_config_android.h b/include/SDL_config_android.h index 46638193d7..f2182165dc 100644 --- a/include/SDL_config_android.h +++ b/include/SDL_config_android.h @@ -46,7 +46,6 @@ #define HAVE_STDIO_H 1 #define HAVE_STRING_H 1 #define HAVE_SYS_TYPES_H 1 -#define HAVE_LIBUNWIND_H 1 /* C library functions */ #define HAVE_MALLOC 1 From ca26ebea897b9ab050c1058055a55b970e3673ac Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 12 Oct 2017 14:25:07 -0700 Subject: [PATCH 66/95] Fixed bug 3877 - missing SDLCALL in SDLTest_ExampleHitTestCallback Ozkan Sezer Following trivial patch adds missing SDLCALL to SDLTest_ExampleHitTestCallback() --- src/test/SDL_test_common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/SDL_test_common.c b/src/test/SDL_test_common.c index f288d2330b..d3101ea704 100644 --- a/src/test/SDL_test_common.c +++ b/src/test/SDL_test_common.c @@ -676,7 +676,7 @@ SDLTest_LoadIcon(const char *file) return (icon); } -static SDL_HitTestResult +static SDL_HitTestResult SDLCALL SDLTest_ExampleHitTestCallback(SDL_Window *win, const SDL_Point *area, void *data) { int w, h; From cfeb5a914fc91b04caceaf5832405fd9a38d3b0a Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 12 Oct 2017 14:44:54 -0700 Subject: [PATCH 67/95] Fixed compiler warning --- src/test/SDL_test_memory.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/SDL_test_memory.c b/src/test/SDL_test_memory.c index 15395e889a..69cb91ecc3 100644 --- a/src/test/SDL_test_memory.c +++ b/src/test/SDL_test_memory.c @@ -250,14 +250,14 @@ void SDLTest_LogAllocations() total_allocated = 0; for (index = 0; index < SDL_arraysize(s_tracked_allocations); ++index) { for (entry = s_tracked_allocations[index]; entry; entry = entry->next) { - SDL_snprintf(line, sizeof(line), "Allocation %d: %lu bytes\n", count, entry->size); + SDL_snprintf(line, sizeof(line), "Allocation %d: %d bytes\n", count, (int)entry->size); ADD_LINE(); /* Start at stack index 1 to skip our tracking functions */ for (stack_index = 1; stack_index < SDL_arraysize(entry->stack); ++stack_index) { if (!entry->stack[stack_index]) { break; } - SDL_snprintf(line, sizeof(line), "\t0x%llx: %s\n", entry->stack[stack_index], entry->stack_names[stack_index]); + SDL_snprintf(line, sizeof(line), "\t0x%"SDL_PRIX64": %s\n", entry->stack[stack_index], entry->stack_names[stack_index]); ADD_LINE(); } total_allocated += entry->size; From f27aafba7568117bd0b735337a3c4932eab750e8 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 12 Oct 2017 14:46:28 -0700 Subject: [PATCH 68/95] Use the lower-case hex output to match other stack trace printouts --- src/test/SDL_test_memory.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/SDL_test_memory.c b/src/test/SDL_test_memory.c index 69cb91ecc3..b060332eb8 100644 --- a/src/test/SDL_test_memory.c +++ b/src/test/SDL_test_memory.c @@ -257,7 +257,7 @@ void SDLTest_LogAllocations() if (!entry->stack[stack_index]) { break; } - SDL_snprintf(line, sizeof(line), "\t0x%"SDL_PRIX64": %s\n", entry->stack[stack_index], entry->stack_names[stack_index]); + SDL_snprintf(line, sizeof(line), "\t0x%"SDL_PRIx64": %s\n", entry->stack[stack_index], entry->stack_names[stack_index]); ADD_LINE(); } total_allocated += entry->size; From d0e8872e2d384002b336e7b8bc1767d1f4d2e66d Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 12 Oct 2017 17:17:09 -0700 Subject: [PATCH 69/95] Fixed compiler warning --- include/SDL_stdinc.h | 2 +- src/stdlib/SDL_malloc.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/SDL_stdinc.h b/include/SDL_stdinc.h index 16100b8b87..f7ac33a904 100644 --- a/include/SDL_stdinc.h +++ b/include/SDL_stdinc.h @@ -376,7 +376,7 @@ extern DECLSPEC int SDLCALL SDL_SetMemoryFunctions(SDL_malloc_func malloc_func, /** * \brief Get the number of outstanding (unfreed) allocations */ -extern DECLSPEC int SDLCALL SDL_GetNumAllocations(); +extern DECLSPEC int SDLCALL SDL_GetNumAllocations(void); extern DECLSPEC char *SDLCALL SDL_getenv(const char *name); extern DECLSPEC int SDLCALL SDL_setenv(const char *name, const char *value, int overwrite); diff --git a/src/stdlib/SDL_malloc.c b/src/stdlib/SDL_malloc.c index c2cb1f3a63..225b19000a 100644 --- a/src/stdlib/SDL_malloc.c +++ b/src/stdlib/SDL_malloc.c @@ -5312,7 +5312,7 @@ int SDL_SetMemoryFunctions(SDL_malloc_func malloc_func, return 0; } -int SDL_GetNumAllocations() +int SDL_GetNumAllocations(void) { return SDL_AtomicGet(&s_mem.num_allocations); } From e043600c676ec882db2376ede09005e1b5ba2dfa Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 12 Oct 2017 17:21:57 -0700 Subject: [PATCH 70/95] Build both 32 and 64-bit architectures in the OSX Framework --- Xcode/SDL/SDL.xcodeproj/project.pbxproj | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Xcode/SDL/SDL.xcodeproj/project.pbxproj b/Xcode/SDL/SDL.xcodeproj/project.pbxproj index 4673d2c416..4208d9af94 100755 --- a/Xcode/SDL/SDL.xcodeproj/project.pbxproj +++ b/Xcode/SDL/SDL.xcodeproj/project.pbxproj @@ -2843,6 +2843,7 @@ 00CFA622106A567900758660 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; CLANG_LINK_OBJC_RUNTIME = NO; COMBINE_HIDPI_IMAGES = YES; DYLIB_COMPATIBILITY_VERSION = 1.0.0; @@ -2934,6 +2935,7 @@ 00CFA628106A568900758660 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; CLANG_LINK_OBJC_RUNTIME = NO; COMBINE_HIDPI_IMAGES = YES; DYLIB_COMPATIBILITY_VERSION = 1.0.0; From 490266da96215a8c087b67009be8b7219d6cf50c Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 13 Oct 2017 01:15:29 -0400 Subject: [PATCH 71/95] coreaudio: changed device close procedure to prevent long hangs in some cases. The audioqueue thread needs to keep running, and processing the CFRunLoop until the AudioQueue is disposed of, otherwise CoreAudio will hang waiting for final data to feed the device. At least, I think this is how it all works. It definitely fixes the bug here! Since AudioQueueDispose() calls AudioQueueStop() internally, there's no need for our thread to handle this, either, which is good because the AudioQueue would be disposed by this point. So now the AudioQueue is disposed first, and then our thread is joined, and everything works out okay. Just in case, we mark the device "paused" before setting everything in motion, so any further callbacks from CoreAudio will write silence and not fire the app's audio callback again. Fixes Bugzilla #3868. --- src/audio/coreaudio/SDL_coreaudio.m | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/audio/coreaudio/SDL_coreaudio.m b/src/audio/coreaudio/SDL_coreaudio.m index 33c239d736..dc04dbe28f 100644 --- a/src/audio/coreaudio/SDL_coreaudio.m +++ b/src/audio/coreaudio/SDL_coreaudio.m @@ -541,15 +541,18 @@ static BOOL update_audio_session(_THIS, SDL_bool open) update_audio_session(this, SDL_FALSE); #endif - if (this->hidden->thread) { - SDL_AtomicSet(&this->hidden->shutdown, 1); - SDL_WaitThread(this->hidden->thread, NULL); - } + /* if callback fires again, feed silence; don't call into the app. */ + SDL_AtomicSet(&this->paused, 1); if (this->hidden->audioQueue) { AudioQueueDispose(this->hidden->audioQueue, 1); } + if (this->hidden->thread) { + SDL_AtomicSet(&this->hidden->shutdown, 1); + SDL_WaitThread(this->hidden->thread, NULL); + } + if (this->hidden->ready_semaphore) { SDL_DestroySemaphore(this->hidden->ready_semaphore); } @@ -731,12 +734,9 @@ static BOOL update_audio_session(_THIS, SDL_bool open) CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.10, 1); } - if (this->iscapture) { /* just stop immediately for capture devices. */ - AudioQueueStop(this->hidden->audioQueue, 1); - } else { /* Drain off any pending playback. */ + if (!this->iscapture) { /* Drain off any pending playback. */ const CFTimeInterval secs = (((this->spec.size / (SDL_AUDIO_BITSIZE(this->spec.format) / 8)) / this->spec.channels) / ((CFTimeInterval) this->spec.freq)) * 2.0; CFRunLoopRunInMode(kCFRunLoopDefaultMode, secs, 0); - AudioQueueStop(this->hidden->audioQueue, 0); } return 0; From 4b88d378880df59e9bad4263dc1d8ca86ceb39f9 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 13 Oct 2017 09:50:04 -0700 Subject: [PATCH 72/95] Fixed bug 3879 - add missing SDLCALL to SDLTest_TrackedMalloc & co. Ozkan Sezer The attached trivial patch adds missing SDLCALL to SDLTest_TrackedMalloc & co. --- src/test/SDL_test_memory.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/SDL_test_memory.c b/src/test/SDL_test_memory.c index b060332eb8..3a2dc71081 100644 --- a/src/test/SDL_test_memory.c +++ b/src/test/SDL_test_memory.c @@ -144,7 +144,7 @@ static void SDL_UntrackAllocation(void *mem) } } -static void *SDLTest_TrackedMalloc(size_t size) +static void * SDLCALL SDLTest_TrackedMalloc(size_t size) { void *mem; @@ -155,7 +155,7 @@ static void *SDLTest_TrackedMalloc(size_t size) return mem; } -static void *SDLTest_TrackedCalloc(size_t nmemb, size_t size) +static void * SDLCALL SDLTest_TrackedCalloc(size_t nmemb, size_t size) { void *mem; @@ -166,7 +166,7 @@ static void *SDLTest_TrackedCalloc(size_t nmemb, size_t size) return mem; } -static void *SDLTest_TrackedRealloc(void *ptr, size_t size) +static void * SDLCALL SDLTest_TrackedRealloc(void *ptr, size_t size) { void *mem; @@ -181,7 +181,7 @@ static void *SDLTest_TrackedRealloc(void *ptr, size_t size) return mem; } -static void SDLTest_TrackedFree(void *ptr) +static void SDLCALL SDLTest_TrackedFree(void *ptr) { if (!ptr) { return; From feddaa29eb8c31f10bc6a41b050b93d62ab4bbb1 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 13 Oct 2017 19:30:34 -0700 Subject: [PATCH 73/95] Fixed bug 3880 - X Error upon quit since rev. 11607 Ozkan Sezer Since changeset 11607:db7ee6a1ba6a, I am getting the following error upon quit. Running testsprite2, clicking the mouse, and quiting it is enough to trigger it. This is on my old Fedora9 x86-Linux: X Error of failed request: BadCursor (invalid Cursor parameter) Major opcode of failed request: 2 (X_ChangeWindowAttributes) Resource id in failed request: 0xb057340 Serial number of failed request: 905 Current serial number in output stream: 906 Reverting https://hg.libsdl.org/SDL/rev/db7ee6a1ba6a removes the error. --- src/events/SDL_mouse.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/events/SDL_mouse.c b/src/events/SDL_mouse.c index 794eafe1e6..80c367f88b 100644 --- a/src/events/SDL_mouse.c +++ b/src/events/SDL_mouse.c @@ -580,13 +580,16 @@ SDL_MouseQuit(void) SDL_FreeCursor(cursor); cursor = next; } + mouse->cursors = NULL; if (mouse->def_cursor && mouse->FreeCursor) { mouse->FreeCursor(mouse->def_cursor); + mouse->def_cursor = NULL; } if (mouse->clickstate) { SDL_free(mouse->clickstate); + mouse->clickstate = NULL; } SDL_DelHintCallback(SDL_HINT_MOUSE_NORMAL_SPEED_SCALE, From e2295381252910e9c45df1ead736e0085716672f Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 13 Oct 2017 19:55:07 -0700 Subject: [PATCH 74/95] Android Studio code analyzer fixes --- .../src/org/libsdl/app/SDLActivity.java | 37 ++++++------------- .../src/org/libsdl/app/SDLAudioManager.java | 1 - .../org/libsdl/app/SDLControllerManager.java | 6 +-- 3 files changed, 13 insertions(+), 31 deletions(-) diff --git a/android-project/src/org/libsdl/app/SDLActivity.java b/android-project/src/org/libsdl/app/SDLActivity.java index ae18c572bb..9119473f53 100644 --- a/android-project/src/org/libsdl/app/SDLActivity.java +++ b/android-project/src/org/libsdl/app/SDLActivity.java @@ -2,12 +2,9 @@ import java.io.IOException; import java.io.InputStream; -import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; import java.lang.reflect.Method; +import java.util.Objects; import android.app.*; import android.content.*; @@ -26,7 +23,6 @@ import android.util.SparseArray; import android.graphics.*; import android.graphics.drawable.Drawable; -import android.media.*; import android.hardware.*; import android.content.pm.ActivityInfo; @@ -400,7 +396,6 @@ public void run() { mSurface.handleResume(); mCurrentNativeState = mNextNativeState; } - return; } } @@ -547,7 +542,7 @@ public void setOrientationBis(int w, int h, boolean resizable, String hint) { int orientation = -1; - if (hint != "") { + if (!Objects.equals(hint, "")) { if (hint.contains("LandscapeRight") && hint.contains("LandscapeLeft")) { orientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE; } else if (hint.contains("LandscapeRight")) { @@ -580,8 +575,6 @@ public void setOrientationBis(int w, int h, boolean resizable, String hint) if (orientation != -1) { mSingleton.setRequestedOrientation(orientation); } - - return; } @@ -590,20 +583,17 @@ public void setOrientationBis(int w, int h, boolean resizable, String hint) */ public static boolean isScreenKeyboardShown() { - if (mTextEdit == null) { - return false; - } + if (mTextEdit == null) { + return false; + } - if (mScreenKeyboardShown == false) { - return false; - } + if (!mScreenKeyboardShown) { + return false; + } - InputMethodManager imm = (InputMethodManager) SDL.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); - if (imm.isAcceptingText()) { - return true; - } + InputMethodManager imm = (InputMethodManager) SDL.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); + return imm.isAcceptingText(); - return false; } /** @@ -681,10 +671,7 @@ public static boolean isTextInputEvent(KeyEvent event) { } } - if (event.isPrintingKey() || event.getKeyCode() == KeyEvent.KEYCODE_SPACE) { - return true; - } - return false; + return event.isPrintingKey() || event.getKeyCode() == KeyEvent.KEYCODE_SPACE; } /** @@ -1010,7 +997,6 @@ public static String clipboardGetText() { */ public static void clipboardSetText(String string) { mClipboardHandler.clipboardSetText(string); - return; } } @@ -1604,7 +1590,6 @@ public String clipboardGetText() { @Override public void clipboardSetText(String string) { mClipMgrOld.setText(string); - return; } } diff --git a/android-project/src/org/libsdl/app/SDLAudioManager.java b/android-project/src/org/libsdl/app/SDLAudioManager.java index 66c3fea422..26baf8220a 100644 --- a/android-project/src/org/libsdl/app/SDLAudioManager.java +++ b/android-project/src/org/libsdl/app/SDLAudioManager.java @@ -1,7 +1,6 @@ package org.libsdl.app; import android.media.*; -import android.hardware.*; import android.util.Log; public class SDLAudioManager diff --git a/android-project/src/org/libsdl/app/SDLControllerManager.java b/android-project/src/org/libsdl/app/SDLControllerManager.java index ef946acd59..36294422fc 100644 --- a/android-project/src/org/libsdl/app/SDLControllerManager.java +++ b/android-project/src/org/libsdl/app/SDLControllerManager.java @@ -1,14 +1,12 @@ package org.libsdl.app; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.List; +import java.util.Objects; -import android.app.*; import android.content.Context; -import android.hardware.*; import android.os.*; import android.view.*; import android.util.Log; @@ -268,7 +266,7 @@ class SDLJoystickHandler_API16 extends SDLJoystickHandler_API12 { public String getJoystickDescriptor(InputDevice joystickDevice) { String desc = joystickDevice.getDescriptor(); - if (desc != null && desc != "") { + if (desc != null && !Objects.equals(desc, "")) { return desc; } From 6be3a225027dedd1443b4c67b7dc38a2a4abd1ea Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sun, 15 Oct 2017 21:07:01 -0700 Subject: [PATCH 75/95] Fixed bug 3882 - cmake fix for osx Ozkan Sezer In my cross-build environment with cmake-2.8.12.1, cmake does not add SDL_coreaudio.m to its makefiles and the result is a failure. The fix is simple: set the language to C for it as it is done at other places in CMakeLists.txt. --- CMakeLists.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4af51987e2..73d94077fb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1352,7 +1352,7 @@ elseif(APPLE) # !!! FIXME: we need Carbon for some very old API calls in # !!! FIXME: src/video/cocoa/SDL_cocoakeyboard.c, but we should figure out # !!! FIXME: how to dump those. - if (APPLE AND NOT IOS) + if(NOT IOS) set(SDL_FRAMEWORK_COCOA 1) set(SDL_FRAMEWORK_CARBON 1) endif() @@ -1373,6 +1373,8 @@ elseif(APPLE) if(SDL_AUDIO) set(SDL_AUDIO_DRIVER_COREAUDIO 1) file(GLOB AUDIO_SOURCES ${SDL2_SOURCE_DIR}/src/audio/coreaudio/*.m) + # !!! FIXME: modern CMake doesn't need "LANGUAGE C" for Objective-C. + set_source_files_properties(${AUDIO_SOURCES} PROPERTIES LANGUAGE C) set(SOURCE_FILES ${SOURCE_FILES} ${AUDIO_SOURCES}) set(HAVE_SDL_AUDIO TRUE) set(SDL_FRAMEWORK_COREAUDIO 1) From f277c646cbcc384b5ac5f1af2c891c6397e3d521 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sun, 15 Oct 2017 21:21:19 -0700 Subject: [PATCH 76/95] Fixed bug 3883 - SDL_assert / SDL_PromptAssertion in TTY mode does not accept options ("abriA") shoerbaffen fgets can read a newline and SDL_strcmp will never return zero. --- src/SDL_assert.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/SDL_assert.c b/src/SDL_assert.c index 47309eb7ce..1eca9232d2 100644 --- a/src/SDL_assert.c +++ b/src/SDL_assert.c @@ -278,19 +278,19 @@ SDL_PromptAssertion(const SDL_assert_data *data, void *userdata) break; } - if (SDL_strcmp(buf, "a") == 0) { + if (SDL_strncmp(buf, "a", 1) == 0) { state = SDL_ASSERTION_ABORT; break; - } else if (SDL_strcmp(buf, "b") == 0) { + } else if (SDL_strncmp(buf, "b", 1) == 0) { state = SDL_ASSERTION_BREAK; break; - } else if (SDL_strcmp(buf, "r") == 0) { + } else if (SDL_strncmp(buf, "r", 1) == 0) { state = SDL_ASSERTION_RETRY; break; - } else if (SDL_strcmp(buf, "i") == 0) { + } else if (SDL_strncmp(buf, "i", 1) == 0) { state = SDL_ASSERTION_IGNORE; break; - } else if (SDL_strcmp(buf, "A") == 0) { + } else if (SDL_strncmp(buf, "A", 1) == 0) { state = SDL_ASSERTION_ALWAYS_IGNORE; break; } From eabcaa67e143444144b88e95417b4e4add4c0225 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Mon, 16 Oct 2017 14:39:56 -0700 Subject: [PATCH 77/95] Added min/max macros for the sized SDL datatypes --- include/SDL_stdinc.h | 16 ++++++++++++++++ test/testplatform.c | 20 ++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/include/SDL_stdinc.h b/include/SDL_stdinc.h index f7ac33a904..72402299f2 100644 --- a/include/SDL_stdinc.h +++ b/include/SDL_stdinc.h @@ -146,35 +146,51 @@ typedef enum /** * \brief A signed 8-bit integer type. */ +#define SDL_MAX_SINT8 ((Sint8)0x7F) /* 127 */ +#define SDL_MIN_SINT8 ((Sint8)(~0x7F)) /* -128 */ typedef int8_t Sint8; /** * \brief An unsigned 8-bit integer type. */ +#define SDL_MAX_UINT8 ((Uint8)0xFF) /* 255 */ +#define SDL_MIN_UINT8 ((Uint8)0x00) /* 0 */ typedef uint8_t Uint8; /** * \brief A signed 16-bit integer type. */ +#define SDL_MAX_SINT16 ((Sint16)0x7FFF) /* 32767 */ +#define SDL_MIN_SINT16 ((Sint16)(~0x7FFF)) /* -32768 */ typedef int16_t Sint16; /** * \brief An unsigned 16-bit integer type. */ +#define SDL_MAX_UINT16 ((Uint16)0xFFFF) /* 65535 */ +#define SDL_MIN_UINT16 ((Uint16)0x0000) /* 0 */ typedef uint16_t Uint16; /** * \brief A signed 32-bit integer type. */ +#define SDL_MAX_SINT32 ((Sint32)0x7FFFFFFF) /* 2147483647 */ +#define SDL_MIN_SINT32 ((Sint32)(~0x7FFFFFFF)) /* -2147483648 */ typedef int32_t Sint32; /** * \brief An unsigned 32-bit integer type. */ +#define SDL_MAX_UINT32 ((Uint32)0xFFFFFFFFu) /* 4294967295 */ +#define SDL_MIN_UINT32 ((Uint32)0x00000000) /* 0 */ typedef uint32_t Uint32; /** * \brief A signed 64-bit integer type. */ +#define SDL_MAX_SINT64 ((Sint64)0x7FFFFFFFFFFFFFFFll) /* 9223372036854775807 */ +#define SDL_MIN_SINT64 ((Sint64)(~0x7FFFFFFFFFFFFFFFll)) /* -9223372036854775808 */ typedef int64_t Sint64; /** * \brief An unsigned 64-bit integer type. */ +#define SDL_MAX_UINT64 ((Uint64)0xFFFFFFFFFFFFFFFFull) /* 18446744073709551615 */ +#define SDL_MIN_UINT64 ((Uint64)(0x0000000000000000ull)) /* 0 */ typedef uint64_t Uint64; /* @} *//* Basic data types */ diff --git a/test/testplatform.c b/test/testplatform.c index 001123b7d0..0cba8fe76c 100644 --- a/test/testplatform.c +++ b/test/testplatform.c @@ -30,6 +30,26 @@ TestTypes(SDL_bool verbose) { int error = 0; + SDL_COMPILE_TIME_ASSERT(SDL_MAX_SINT8, SDL_MAX_SINT8 == 127); + SDL_COMPILE_TIME_ASSERT(SDL_MIN_SINT8, SDL_MIN_SINT8 == -128); + SDL_COMPILE_TIME_ASSERT(SDL_MAX_UINT8, SDL_MAX_UINT8 == 255); + SDL_COMPILE_TIME_ASSERT(SDL_MIN_UINT8, SDL_MIN_UINT8 == 0); + + SDL_COMPILE_TIME_ASSERT(SDL_MAX_SINT16, SDL_MAX_SINT16 == 32767); + SDL_COMPILE_TIME_ASSERT(SDL_MIN_SINT16, SDL_MIN_SINT16 == -32768); + SDL_COMPILE_TIME_ASSERT(SDL_MAX_UINT16, SDL_MAX_UINT16 == 65535); + SDL_COMPILE_TIME_ASSERT(SDL_MIN_UINT16, SDL_MIN_UINT16 == 0); + + SDL_COMPILE_TIME_ASSERT(SDL_MAX_SINT32, SDL_MAX_SINT32 == 2147483647); + SDL_COMPILE_TIME_ASSERT(SDL_MIN_SINT32, SDL_MIN_SINT32 == ~0x7fffffff); /* Instead of -2147483648, which is treated as unsigned by some compilers */ + SDL_COMPILE_TIME_ASSERT(SDL_MAX_UINT32, SDL_MAX_UINT32 == 4294967295u); + SDL_COMPILE_TIME_ASSERT(SDL_MIN_UINT32, SDL_MIN_UINT32 == 0); + + SDL_COMPILE_TIME_ASSERT(SDL_MAX_SINT64, SDL_MAX_SINT64 == 9223372036854775807ll); + SDL_COMPILE_TIME_ASSERT(SDL_MIN_SINT64, SDL_MIN_SINT64 == ~0x7fffffffffffffffll); /* Instead of -9223372036854775808, which is treated as unsigned by compilers */ + SDL_COMPILE_TIME_ASSERT(SDL_MAX_UINT64, SDL_MAX_UINT64 == 18446744073709551615ull); + SDL_COMPILE_TIME_ASSERT(SDL_MIN_UINT64, SDL_MIN_UINT64 == 0); + if (badsize(sizeof(Uint8), 1)) { if (verbose) SDL_Log("sizeof(Uint8) != 1, instead = %u\n", From a381cbeb605c9e8930d7480c7f1c10e813661045 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Mon, 16 Oct 2017 14:57:42 -0700 Subject: [PATCH 78/95] Fixed bug 3890 - Incomplete fix for CVE-2017-2888 Felix Geyer http://hg.libsdl.org/SDL/rev/7e0f1498ddb5 tries to fix CVE-2017-2888. Unfortunately compilers may optimize the second condition "(size / surface->pitch) != surface->h" away. See https://bugzilla.redhat.com/show_bug.cgi?id=1500623#c2 I've verified that this is also the case on Debian unstable (gcc 7.2). --- src/video/SDL_surface.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/video/SDL_surface.c b/src/video/SDL_surface.c index 2c64291db0..38addea004 100644 --- a/src/video/SDL_surface.c +++ b/src/video/SDL_surface.c @@ -37,6 +37,10 @@ SDL_ConvertPixels_ARGB8888_to_YUV(int width, int height, const void *src, int src_pitch, Uint32 dst_format, void *dst); +/* Check to make sure we can safely check multiplication of surface w and pitch and it won't overflow size_t */ +SDL_COMPILE_TIME_ASSERT(surface_size_assumptions, + sizeof(int) == sizeof(Sint32) && sizeof(size_t) >= sizeof(Sint32)); + /* Public routines */ /* @@ -91,15 +95,16 @@ SDL_CreateRGBSurfaceWithFormat(Uint32 flags, int width, int height, int depth, /* Get the pixels */ if (surface->w && surface->h) { - int size = (surface->h * surface->pitch); - if (size < 0 || (size / surface->pitch) != surface->h) { + /* Assumptions checked in surface_size_assumptions assert above */ + Sint64 size = ((Sint64)surface->h * surface->pitch); + if (size < 0 || size > SDL_MAX_SINT32) { /* Overflow... */ SDL_FreeSurface(surface); SDL_OutOfMemory(); return NULL; } - surface->pixels = SDL_malloc(size); + surface->pixels = SDL_malloc((size_t)size); if (!surface->pixels) { SDL_FreeSurface(surface); SDL_OutOfMemory(); From 4c671dc9af488470ae75a67c89307e5173baba89 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Mon, 16 Oct 2017 15:22:40 -0700 Subject: [PATCH 79/95] Fixed compiler warning on iOS --- src/joystick/steam/SDL_steamcontroller.c | 4 ++-- src/joystick/steam/SDL_steamcontroller.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/joystick/steam/SDL_steamcontroller.c b/src/joystick/steam/SDL_steamcontroller.c index e91830a49e..800fb46f03 100644 --- a/src/joystick/steam/SDL_steamcontroller.c +++ b/src/joystick/steam/SDL_steamcontroller.c @@ -37,7 +37,7 @@ void SDL_GetSteamControllerInputs(int *nbuttons, int *naxes, int *nhats) *nhats = 0; } -void SDL_UpdateSteamControllers() +void SDL_UpdateSteamControllers(void) { } @@ -45,7 +45,7 @@ void SDL_UpdateSteamController(SDL_Joystick *joystick) { } -void SDL_QuitSteamControllers() +void SDL_QuitSteamControllers(void) { } diff --git a/src/joystick/steam/SDL_steamcontroller.h b/src/joystick/steam/SDL_steamcontroller.h index 30a43cb19e..bb0ec2a196 100644 --- a/src/joystick/steam/SDL_steamcontroller.h +++ b/src/joystick/steam/SDL_steamcontroller.h @@ -26,8 +26,8 @@ typedef void (*SteamControllerDisconnectedCallback_t)(int device_instance); void SDL_InitSteamControllers(SteamControllerConnectedCallback_t connectedCallback, SteamControllerDisconnectedCallback_t disconnectedCallback); void SDL_GetSteamControllerInputs(int *nbuttons, int *naxes, int *nhats); -void SDL_UpdateSteamControllers(); +void SDL_UpdateSteamControllers(void); void SDL_UpdateSteamController(SDL_Joystick *joystick); -void SDL_QuitSteamControllers(); +void SDL_QuitSteamControllers(void); /* vi: set ts=4 sw=4 expandtab: */ From 84c7d4a1d25fac63fe8c777a1df9b3e2f45b229e Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Wed, 18 Oct 2017 08:52:04 -0700 Subject: [PATCH 80/95] Fixed bug 3821 - Allow SDL_CreateWindow and SDL_CreateRenderer with OpenGL ES 3.0 (GLES3) for Angle (Windows) Carlos Angle supports GLES3 but when using these functions (SDL_CreateWindow and SDL_CreateRenderer), defaults again to GLES2.0. A current workaround (hack) to retrieve a GLES3.0 context with Angle is: 1) set SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); after InitSDL AND after calling SDL_CreateWindow (before SDL_CreateRenderer) 2) Comment lines 2032-2044 in SDL_render_gles2.c, funtion GLES2_CreateRenderer window_flags = SDL_GetWindowFlags(window); if (!(window_flags & SDL_WINDOW_OPENGL) || profile_mask != SDL_GL_CONTEXT_PROFILE_ES || major != RENDERER_CONTEXT_MAJOR || minor != RENDERER_CONTEXT_MINOR) { changed_window = SDL_TRUE; SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, RENDERER_CONTEXT_MAJOR); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, RENDERER_CONTEXT_MINOR); if (SDL_RecreateWindow(window, window_flags | SDL_WINDOW_OPENGL) < 0) { goto error; } } This retrives a GLES3 context as confirmed using glGetString(GL_VERSION). This should be fixed by modifying a few if's. --- src/render/opengles2/SDL_render_gles2.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/render/opengles2/SDL_render_gles2.c b/src/render/opengles2/SDL_render_gles2.c index d5d42c3435..bd343cf4fe 100644 --- a/src/render/opengles2/SDL_render_gles2.c +++ b/src/render/opengles2/SDL_render_gles2.c @@ -2031,8 +2031,9 @@ GLES2_CreateRenderer(SDL_Window *window, Uint32 flags) } window_flags = SDL_GetWindowFlags(window); + /* OpenGL ES 3.0 is a superset of OpenGL ES 2.0 */ if (!(window_flags & SDL_WINDOW_OPENGL) || - profile_mask != SDL_GL_CONTEXT_PROFILE_ES || major != RENDERER_CONTEXT_MAJOR || minor != RENDERER_CONTEXT_MINOR) { + profile_mask != SDL_GL_CONTEXT_PROFILE_ES || major < RENDERER_CONTEXT_MAJOR) { changed_window = SDL_TRUE; SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); From 5b5c7f95014c3059d14d1a27c5a791bfc2a5bfad Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Wed, 18 Oct 2017 15:54:05 -0700 Subject: [PATCH 81/95] Added audio stream conversion functions: SDL_NewAudioStream SDL_AudioStreamPut SDL_AudioStreamGet SDL_AudioStreamAvailable SDL_AudioStreamClear SDL_FreeAudioStream --- WhatsNew.txt | 7 ++ include/SDL_audio.h | 102 +++++++++++++++++++++++++++++- src/audio/SDL_audio_c.h | 40 ------------ src/audio/SDL_audiocvt.c | 41 ++++++------ src/dynapi/SDL_dynapi_overrides.h | 6 ++ src/dynapi/SDL_dynapi_procs.h | 6 ++ 6 files changed, 140 insertions(+), 62 deletions(-) diff --git a/WhatsNew.txt b/WhatsNew.txt index 04eeaad710..3910359ae7 100644 --- a/WhatsNew.txt +++ b/WhatsNew.txt @@ -6,6 +6,13 @@ This is a list of major changes in SDL's version history. --------------------------------------------------------------------------- General: +* Added audio stream conversion functions: + SDL_NewAudioStream + SDL_AudioStreamPut + SDL_AudioStreamGet + SDL_AudioStreamAvailable + SDL_AudioStreamClear + SDL_FreeAudioStream * Added functions to query and set the SDL memory allocation functions: SDL_GetMemoryFunctions() SDL_SetMemoryFunctions() diff --git a/include/SDL_audio.h b/include/SDL_audio.h index 53277cb7e9..b30c409269 100644 --- a/include/SDL_audio.h +++ b/include/SDL_audio.h @@ -477,6 +477,106 @@ extern DECLSPEC int SDLCALL SDL_BuildAudioCVT(SDL_AudioCVT * cvt, */ extern DECLSPEC int SDLCALL SDL_ConvertAudio(SDL_AudioCVT * cvt); +/* SDL_AudioStream is a new audio conversion interface. + The benefits vs SDL_AudioCVT: + - it can handle resampling data in chunks without generating + artifacts, when it doesn't have the complete buffer available. + - it can handle incoming data in any variable size. + - You push data as you have it, and pull it when you need it + */ +/* this is opaque to the outside world. */ +struct _SDL_AudioStream; +typedef struct _SDL_AudioStream SDL_AudioStream; + +/** + * Create a new audio stream + * + * \param src_format The format of the source audio + * \param src_channels The number of channels of the source audio + * \param src_rate The sampling rate of the source audio + * \param dst_format The format of the desired audio output + * \param dst_channels The number of channels of the desired audio output + * \param dst_rate The sampling rate of the desired audio output + * \return 0 on success, or -1 on error. + * + * \sa SDL_AudioStreamPut + * \sa SDL_AudioStreamGet + * \sa SDL_AudioStreamAvailable + * \sa SDL_AudioStreamClear + * \sa SDL_FreeAudioStream + */ +extern DECLSPEC SDL_AudioStream * SDLCALL SDL_NewAudioStream(const SDL_AudioFormat src_format, + const Uint8 src_channels, + const int src_rate, + const SDL_AudioFormat dst_format, + const Uint8 dst_channels, + const int dst_rate); + +/** + * Add data to be converted/resampled to the stream + * + * \param stream The stream the audio data is being added to + * \param buf A pointer to the audio data to add + * \param int The number of bytes to write to the stream + * \return 0 on success, or -1 on error. + * + * \sa SDL_NewAudioStream + * \sa SDL_AudioStreamGet + * \sa SDL_AudioStreamAvailable + * \sa SDL_AudioStreamClear + * \sa SDL_FreeAudioStream + */ +extern DECLSPEC int SDLCALL SDL_AudioStreamPut(SDL_AudioStream *stream, const void *buf, int len); + +/** + * Get converted/resampled data from the stream + * + * \param stream The stream the audio is being requested from + * \param buf A buffer to fill with audio data + * \param len The maximum number of bytes to fill + * \return The number of bytes read from the stream, or -1 on error + * + * \sa SDL_NewAudioStream + * \sa SDL_AudioStreamPut + * \sa SDL_AudioStreamAvailable + * \sa SDL_AudioStreamClear + * \sa SDL_FreeAudioStream + */ +extern DECLSPEC int SDLCALL SDL_AudioStreamGet(SDL_AudioStream *stream, void *buf, int len); + +/** + * Get the number of converted/resampled bytes available + * + * \sa SDL_NewAudioStream + * \sa SDL_AudioStreamPut + * \sa SDL_AudioStreamGet + * \sa SDL_AudioStreamClear + * \sa SDL_FreeAudioStream + */ +extern DECLSPEC int SDLCALL SDL_AudioStreamAvailable(SDL_AudioStream *stream); + +/** + * Clear any pending data in the stream without converting it + * + * \sa SDL_NewAudioStream + * \sa SDL_AudioStreamPut + * \sa SDL_AudioStreamGet + * \sa SDL_AudioStreamAvailable + * \sa SDL_FreeAudioStream + */ +extern DECLSPEC void SDLCALL SDL_AudioStreamClear(SDL_AudioStream *stream); + +/** + * Free an audio stream + * + * \sa SDL_NewAudioStream + * \sa SDL_AudioStreamPut + * \sa SDL_AudioStreamGet + * \sa SDL_AudioStreamAvailable + * \sa SDL_AudioStreamClear + */ +extern DECLSPEC void SDLCALL SDL_FreeAudioStream(SDL_AudioStream *stream); + #define SDL_MIX_MAXVOLUME 128 /** * This takes two audio buffers of the playing audio format and mixes @@ -532,7 +632,7 @@ extern DECLSPEC void SDLCALL SDL_MixAudioFormat(Uint8 * dst, * \param dev The device ID to which we will queue audio. * \param data The data to queue to the device for later playback. * \param len The number of bytes (not samples!) to which (data) points. - * \return zero on success, -1 on error. + * \return 0 on success, or -1 on error. * * \sa SDL_GetQueuedAudioSize * \sa SDL_ClearQueuedAudio diff --git a/src/audio/SDL_audio_c.h b/src/audio/SDL_audio_c.h index 58ecf10a5e..38c5bbb77d 100644 --- a/src/audio/SDL_audio_c.h +++ b/src/audio/SDL_audio_c.h @@ -74,46 +74,6 @@ extern SDL_AudioFilter SDL_Convert_F32_to_S32; extern int SDL_PrepareResampleFilter(void); extern void SDL_FreeResampleFilter(void); - -/* SDL_AudioStream is a new audio conversion interface. It - might eventually become a public API. - The benefits vs SDL_AudioCVT: - - it can handle resampling data in chunks without generating - artifacts, when it doesn't have the complete buffer available. - - it can handle incoming data in any variable size. - - You push data as you have it, and pull it when you need it - - (Note that currently this converts as data is put into the stream, so - you need to push more than a handful of bytes if you want decent - resampling. This can be changed later.) - */ - -/* this is opaque to the outside world. */ -typedef struct SDL_AudioStream SDL_AudioStream; - -/* create a new stream */ -extern SDL_AudioStream *SDL_NewAudioStream(const SDL_AudioFormat src_format, - const Uint8 src_channels, - const int src_rate, - const SDL_AudioFormat dst_format, - const Uint8 dst_channels, - const int dst_rate); - -/* add data to be converted/resampled to the stream */ -extern int SDL_AudioStreamPut(SDL_AudioStream *stream, const void *buf, const Uint32 len); - -/* get converted/resampled data from the stream */ -extern int SDL_AudioStreamGet(SDL_AudioStream *stream, void *buf, const Uint32 len); - -/* clear any pending data in the stream without converting it. */ -extern void SDL_AudioStreamClear(SDL_AudioStream *stream); - -/* number of converted/resampled bytes available */ -extern int SDL_AudioStreamAvailable(SDL_AudioStream *stream); - -/* dispose of a stream */ -extern void SDL_FreeAudioStream(SDL_AudioStream *stream); - #endif /* SDL_audio_c_h_ */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/audio/SDL_audiocvt.c b/src/audio/SDL_audiocvt.c index 3f505d7fd8..25fe903f29 100644 --- a/src/audio/SDL_audiocvt.c +++ b/src/audio/SDL_audiocvt.c @@ -1077,7 +1077,7 @@ typedef int (*SDL_ResampleAudioStreamFunc)(SDL_AudioStream *stream, const void * typedef void (*SDL_ResetAudioStreamResamplerFunc)(SDL_AudioStream *stream); typedef void (*SDL_CleanupAudioStreamResamplerFunc)(SDL_AudioStream *stream); -struct SDL_AudioStream +struct _SDL_AudioStream { SDL_AudioCVT cvt_before_resampling; SDL_AudioCVT cvt_after_resampling; @@ -1349,9 +1349,9 @@ SDL_NewAudioStream(const SDL_AudioFormat src_format, } int -SDL_AudioStreamPut(SDL_AudioStream *stream, const void *buf, const Uint32 _buflen) +SDL_AudioStreamPut(SDL_AudioStream *stream, const void *buf, int len) { - int buflen = (int) _buflen; + int buflen = len; int workbuflen; Uint8 *workbuf; Uint8 *resamplebuf = NULL; @@ -1495,34 +1495,19 @@ SDL_AudioStreamPut(SDL_AudioStream *stream, const void *buf, const Uint32 _bufle return buflen ? SDL_WriteToDataQueue(stream->queue, resamplebuf, buflen) : 0; } -void -SDL_AudioStreamClear(SDL_AudioStream *stream) -{ - if (!stream) { - SDL_InvalidParamError("stream"); - } else { - SDL_ClearDataQueue(stream->queue, stream->packetlen * 2); - if (stream->reset_resampler_func) { - stream->reset_resampler_func(stream); - } - stream->first_run = SDL_TRUE; - } -} - - /* get converted/resampled data from the stream */ int -SDL_AudioStreamGet(SDL_AudioStream *stream, void *buf, const Uint32 len) +SDL_AudioStreamGet(SDL_AudioStream *stream, void *buf, int len) { #if DEBUG_AUDIOSTREAM - printf("AUDIOSTREAM: want to get %u converted bytes\n", (unsigned int) len); + printf("AUDIOSTREAM: want to get %d converted bytes\n", len); #endif if (!stream) { return SDL_InvalidParamError("stream"); } else if (!buf) { return SDL_InvalidParamError("buf"); - } else if (len == 0) { + } else if (len <= 0) { return 0; /* nothing to do. */ } else if ((len % stream->dst_sample_frame_size) != 0) { return SDL_SetError("Can't request partial sample frames"); @@ -1538,6 +1523,20 @@ SDL_AudioStreamAvailable(SDL_AudioStream *stream) return stream ? (int) SDL_CountDataQueue(stream->queue) : 0; } +void +SDL_AudioStreamClear(SDL_AudioStream *stream) +{ + if (!stream) { + SDL_InvalidParamError("stream"); + } else { + SDL_ClearDataQueue(stream->queue, stream->packetlen * 2); + if (stream->reset_resampler_func) { + stream->reset_resampler_func(stream); + } + stream->first_run = SDL_TRUE; + } +} + /* dispose of a stream */ void SDL_FreeAudioStream(SDL_AudioStream *stream) diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h index a079e92a3f..07705127f6 100644 --- a/src/dynapi/SDL_dynapi_overrides.h +++ b/src/dynapi/SDL_dynapi_overrides.h @@ -640,3 +640,9 @@ #define SDL_GetMemoryFunctions SDL_GetMemoryFunctions_REAL #define SDL_SetMemoryFunctions SDL_SetMemoryFunctions_REAL #define SDL_GetNumAllocations SDL_GetNumAllocations_REAL +#define SDL_NewAudioStream SDL_NewAudioStream_REAL +#define SDL_AudioStreamPut SDL_AudioStreamPut_REAL +#define SDL_AudioStreamGet SDL_AudioStreamGet_REAL +#define SDL_AudioStreamClear SDL_AudioStreamClear_REAL +#define SDL_AudioStreamAvailable SDL_AudioStreamAvailable_REAL +#define SDL_FreeAudioStream SDL_FreeAudioStream_REAL diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h index 237c54aac5..e1372ef5b9 100644 --- a/src/dynapi/SDL_dynapi_procs.h +++ b/src/dynapi/SDL_dynapi_procs.h @@ -674,3 +674,9 @@ SDL_DYNAPI_PROC(void,SDL_UnlockJoysticks,(void),(),) SDL_DYNAPI_PROC(void,SDL_GetMemoryFunctions,(SDL_malloc_func *a, SDL_calloc_func *b, SDL_realloc_func *c, SDL_free_func *d),(a,b,c,d),) SDL_DYNAPI_PROC(int,SDL_SetMemoryFunctions,(SDL_malloc_func a, SDL_calloc_func b, SDL_realloc_func c, SDL_free_func d),(a,b,c,d),return) SDL_DYNAPI_PROC(int,SDL_GetNumAllocations,(void),(),return) +SDL_DYNAPI_PROC(SDL_AudioStream*,SDL_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) +SDL_DYNAPI_PROC(int,SDL_AudioStreamPut,(SDL_AudioStream *a, const void *b, int c),(a,b,c),return) +SDL_DYNAPI_PROC(int,SDL_AudioStreamGet,(SDL_AudioStream *a, void *b, int c),(a,b,c),return) +SDL_DYNAPI_PROC(void,SDL_AudioStreamClear,(SDL_AudioStream *a),(a),) +SDL_DYNAPI_PROC(int,SDL_AudioStreamAvailable,(SDL_AudioStream *a),(a),return) +SDL_DYNAPI_PROC(void,SDL_FreeAudioStream,(SDL_AudioStream *a),(a),) From 4f07312be20b01513b259037f0172707d9c92b5d Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Wed, 18 Oct 2017 19:26:36 -0700 Subject: [PATCH 82/95] Added a staging buffer to the audio stream so that we can accumulate small amounts of data if needed when resampling --- src/audio/SDL_audiocvt.c | 110 +++++++++++++++++++++++++++++---------- 1 file changed, 82 insertions(+), 28 deletions(-) diff --git a/src/audio/SDL_audiocvt.c b/src/audio/SDL_audiocvt.c index 25fe903f29..5bc70160d4 100644 --- a/src/audio/SDL_audiocvt.c +++ b/src/audio/SDL_audiocvt.c @@ -1083,6 +1083,9 @@ struct _SDL_AudioStream SDL_AudioCVT cvt_after_resampling; SDL_DataQueue *queue; SDL_bool first_run; + Uint8 *staging_buffer; + int staging_buffer_size; + int staging_buffer_filled; Uint8 *work_buffer_base; /* maybe unaligned pointer from SDL_realloc(). */ int work_buffer_len; int src_sample_frame_size; @@ -1293,7 +1296,17 @@ SDL_NewAudioStream(const SDL_AudioFormat src_format, return NULL; } - /* Not resampling? It's an easy conversion (and maybe not even that!). */ + retval->staging_buffer_size = ((retval->resampler_padding_samples / retval->pre_resample_channels) * retval->src_sample_frame_size); + if (retval->staging_buffer_size > 0) { + retval->staging_buffer = (Uint8 *) SDL_malloc(retval->staging_buffer_size); + if (retval->resampler_padding == NULL) { + SDL_FreeAudioStream(retval); + SDL_OutOfMemory(); + return NULL; + } + } + + /* Not resampling? It's an easy conversion (and maybe not even that!) */ if (src_rate == dst_rate) { retval->cvt_before_resampling.needed = SDL_FALSE; if (SDL_BuildAudioCVT(&retval->cvt_after_resampling, src_format, src_channels, dst_rate, dst_format, dst_channels, dst_rate) < 0) { @@ -1348,8 +1361,8 @@ SDL_NewAudioStream(const SDL_AudioFormat src_format, return retval; } -int -SDL_AudioStreamPut(SDL_AudioStream *stream, const void *buf, int len) +static int +SDL_AudioStreamPutInternal(SDL_AudioStream *stream, const void *buf, int len) { int buflen = len; int workbuflen; @@ -1367,36 +1380,11 @@ SDL_AudioStreamPut(SDL_AudioStream *stream, const void *buf, int len) !!! FIXME: isn't a multiple of 16. In these cases, we should chop off !!! FIXME: a few samples at the end and convert them separately. */ - #if DEBUG_AUDIOSTREAM - printf("AUDIOSTREAM: wants to put %d preconverted bytes\n", buflen); - #endif - - if (!stream) { - return SDL_InvalidParamError("stream"); - } else if (!buf) { - return SDL_InvalidParamError("buf"); - } else if (buflen == 0) { - return 0; /* nothing to do. */ - } else if ((buflen % stream->src_sample_frame_size) != 0) { - return SDL_SetError("Can't add partial sample frames"); - } else if (buflen < ((stream->resampler_padding_samples / stream->pre_resample_channels) * stream->src_sample_frame_size)) { - return SDL_SetError("Need to put a larger buffer"); - } - /* no padding prepended on first run. */ neededpaddingbytes = stream->resampler_padding_samples * sizeof (float); paddingbytes = stream->first_run ? 0 : neededpaddingbytes; stream->first_run = SDL_FALSE; - if (!stream->cvt_before_resampling.needed && - (stream->dst_rate == stream->src_rate) && - !stream->cvt_after_resampling.needed) { - #if DEBUG_AUDIOSTREAM - printf("AUDIOSTREAM: no conversion needed at all, queueing %d bytes.\n", buflen); - #endif - return SDL_WriteToDataQueue(stream->queue, buf, buflen); - } - /* Make sure the work buffer can hold all the data we need at once... */ workbuflen = buflen; if (stream->cvt_before_resampling.needed) { @@ -1495,6 +1483,71 @@ SDL_AudioStreamPut(SDL_AudioStream *stream, const void *buf, int len) return buflen ? SDL_WriteToDataQueue(stream->queue, resamplebuf, buflen) : 0; } +int +SDL_AudioStreamPut(SDL_AudioStream *stream, const void *buf, int len) +{ + /* !!! FIXME: several converters can take advantage of SIMD, but only + !!! FIXME: if the data is aligned to 16 bytes. EnsureStreamBufferSize() + !!! FIXME: guarantees the buffer will align, but the + !!! FIXME: converters will iterate over the data backwards if + !!! FIXME: the output grows, and this means we won't align if buflen + !!! FIXME: isn't a multiple of 16. In these cases, we should chop off + !!! FIXME: a few samples at the end and convert them separately. */ + + #if DEBUG_AUDIOSTREAM + printf("AUDIOSTREAM: wants to put %d preconverted bytes\n", buflen); + #endif + + if (!stream) { + return SDL_InvalidParamError("stream"); + } else if (!buf) { + return SDL_InvalidParamError("buf"); + } else if (len == 0) { + return 0; /* nothing to do. */ + } else if ((len % stream->src_sample_frame_size) != 0) { + return SDL_SetError("Can't add partial sample frames"); + } + + if (!stream->cvt_before_resampling.needed && + (stream->dst_rate == stream->src_rate) && + !stream->cvt_after_resampling.needed) { + #if DEBUG_AUDIOSTREAM + printf("AUDIOSTREAM: no conversion needed at all, queueing %d bytes.\n", len); + #endif + return SDL_WriteToDataQueue(stream->queue, buf, len); + } + + while (len > 0) { + int amount; + + /* If we don't have a staging buffer or we're given enough data that + we don't need to store it for later, skip the staging process. + */ + if (!stream->staging_buffer_filled && len >= stream->staging_buffer_size) { + return SDL_AudioStreamPutInternal(stream, buf, len); + } + + /* If there's not enough data to fill the staging buffer, just save it */ + if ((stream->staging_buffer_filled + len) < stream->staging_buffer_size) { + SDL_memcpy(stream->staging_buffer + stream->staging_buffer_filled, buf, len); + stream->staging_buffer_filled += len; + return 0; + } + + /* Fill the staging buffer, process it, and continue */ + amount = (stream->staging_buffer_size - stream->staging_buffer_filled); + SDL_assert(amount > 0); + SDL_memcpy(stream->staging_buffer + stream->staging_buffer_filled, buf, amount); + stream->staging_buffer_filled = 0; + if (SDL_AudioStreamPutInternal(stream, stream->staging_buffer, stream->staging_buffer_size) < 0) { + return -1; + } + buf = (void *)((Uint8 *)buf + amount); + len -= amount; + } + return 0; +} + /* get converted/resampled data from the stream */ int SDL_AudioStreamGet(SDL_AudioStream *stream, void *buf, int len) @@ -1546,6 +1599,7 @@ SDL_FreeAudioStream(SDL_AudioStream *stream) stream->cleanup_resampler_func(stream); } SDL_FreeDataQueue(stream->queue); + SDL_free(stream->staging_buffer); SDL_free(stream->work_buffer_base); SDL_free(stream->resampler_padding); SDL_free(stream); From a4358894c822c8dcae6a287b14833a16f77c0288 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Wed, 18 Oct 2017 19:30:47 -0700 Subject: [PATCH 83/95] Fixed bug 3876 - Resampling of certain sounds adds heavy distortion Simon Hug Patch that adds [-1, 1] clamping to the scalar audio type conversions. This may come from the SDL_Convert_F32_to_X_Scalar functions. They don't clamp the float value to [-1, 1] and when they cast it to the target integer it may be too large or too small for the type and get truncated, causing horrible noise. The attached patch throws clamping in, but I don't know if that's the preferred way to fix this. For x86 (without SSE) the compiler (I tested MSVC) seems to throw a horrible amount of x87 code in it. It's a bit better with SSE, but probably still quite the performance hit. And SSE2 uses a branchless approach with maxss and minss. --- src/audio/SDL_audiotypecvt.c | 45 ++++++++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 5 deletions(-) diff --git a/src/audio/SDL_audiotypecvt.c b/src/audio/SDL_audiotypecvt.c index 86f883c0b0..bd717f4cc2 100644 --- a/src/audio/SDL_audiotypecvt.c +++ b/src/audio/SDL_audiotypecvt.c @@ -170,7 +170,14 @@ SDL_Convert_F32_to_S8_Scalar(SDL_AudioCVT *cvt, SDL_AudioFormat format) LOG_DEBUG_CONVERT("AUDIO_F32", "AUDIO_S8"); for (i = cvt->len_cvt / sizeof (float); i; --i, ++src, ++dst) { - *dst = (Sint8) (*src * 127.0f); + const float sample = *src; + if (sample > 1.0f) { + *dst = 127; + } else if (sample < -1.0f) { + *dst = -127; + } else { + *dst = (Sint8)(sample * 127.0f); + } } cvt->len_cvt /= 4; @@ -189,7 +196,14 @@ SDL_Convert_F32_to_U8_Scalar(SDL_AudioCVT *cvt, SDL_AudioFormat format) LOG_DEBUG_CONVERT("AUDIO_F32", "AUDIO_U8"); for (i = cvt->len_cvt / sizeof (float); i; --i, ++src, ++dst) { - *dst = (Uint8) ((*src + 1.0f) * 127.0f); + const float sample = *src; + if (sample > 1.0f) { + *dst = 255; + } else if (sample < -1.0f) { + *dst = 0; + } else { + *dst = (Uint8)((sample + 1.0f) * 127.0f); + } } cvt->len_cvt /= 4; @@ -208,7 +222,14 @@ SDL_Convert_F32_to_S16_Scalar(SDL_AudioCVT *cvt, SDL_AudioFormat format) LOG_DEBUG_CONVERT("AUDIO_F32", "AUDIO_S16"); for (i = cvt->len_cvt / sizeof (float); i; --i, ++src, ++dst) { - *dst = (Sint16) (*src * 32767.0f); + const float sample = *src; + if (sample > 1.0f) { + *dst = 32767; + } else if (sample < -1.0f) { + *dst = -32767; + } else { + *dst = (Sint16)(sample * 32767.0f); + } } cvt->len_cvt /= 2; @@ -227,7 +248,14 @@ SDL_Convert_F32_to_U16_Scalar(SDL_AudioCVT *cvt, SDL_AudioFormat format) LOG_DEBUG_CONVERT("AUDIO_F32", "AUDIO_U16"); for (i = cvt->len_cvt / sizeof (float); i; --i, ++src, ++dst) { - *dst = (Uint16) ((*src + 1.0f) * 32767.0f); + const float sample = *src; + if (sample > 1.0f) { + *dst = 65534; + } else if (sample < -1.0f) { + *dst = 0; + } else { + *dst = (Uint16)((sample + 1.0f) * 32767.0f); + } } cvt->len_cvt /= 2; @@ -246,7 +274,14 @@ SDL_Convert_F32_to_S32_Scalar(SDL_AudioCVT *cvt, SDL_AudioFormat format) LOG_DEBUG_CONVERT("AUDIO_F32", "AUDIO_S32"); for (i = cvt->len_cvt / sizeof (float); i; --i, ++src, ++dst) { - *dst = (Sint32) (((double) *src) * 2147483647.0); + const float sample = *src; + if (sample > 1.0f) { + *dst = 2147483647; + } else if (sample < -1.0f) { + *dst = -2147483647; + } else { + *dst = (Sint32)((double)sample * 2147483647.0); + } } if (cvt->filters[++cvt->filter_index]) { From 2a14d91afa157851bff96fa0ec37add272d18a11 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 18 Oct 2017 23:49:46 -0400 Subject: [PATCH 84/95] Check correct variable for malloc() results. --- src/audio/SDL_audiocvt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/audio/SDL_audiocvt.c b/src/audio/SDL_audiocvt.c index 5bc70160d4..3a10fc9f06 100644 --- a/src/audio/SDL_audiocvt.c +++ b/src/audio/SDL_audiocvt.c @@ -1299,7 +1299,7 @@ SDL_NewAudioStream(const SDL_AudioFormat src_format, retval->staging_buffer_size = ((retval->resampler_padding_samples / retval->pre_resample_channels) * retval->src_sample_frame_size); if (retval->staging_buffer_size > 0) { retval->staging_buffer = (Uint8 *) SDL_malloc(retval->staging_buffer_size); - if (retval->resampler_padding == NULL) { + if (retval->staging_buffer == NULL) { SDL_FreeAudioStream(retval); SDL_OutOfMemory(); return NULL; From ce12bd11ff5a4426529a6fc6ef7f230003580dcd Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 19 Oct 2017 13:54:56 -0700 Subject: [PATCH 85/95] Don't use DPAD devices as joystick input on Android --- .../src/org/libsdl/app/SDLControllerManager.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/android-project/src/org/libsdl/app/SDLControllerManager.java b/android-project/src/org/libsdl/app/SDLControllerManager.java index 36294422fc..6d97fa8e9a 100644 --- a/android-project/src/org/libsdl/app/SDLControllerManager.java +++ b/android-project/src/org/libsdl/app/SDLControllerManager.java @@ -92,17 +92,16 @@ public static boolean isDeviceSDLJoystick(int deviceId) { if ((sources & InputDevice.SOURCE_CLASS_JOYSTICK) == InputDevice.SOURCE_CLASS_JOYSTICK) { Log.v(TAG, "Input device " + device.getName() + " is a joystick."); } + /* A lot of things are a DPAD that we don't want to use as a joystick (e.g. gpio input, etc.) if ((sources & InputDevice.SOURCE_DPAD) == InputDevice.SOURCE_DPAD) { Log.v(TAG, "Input device " + device.getName() + " is a dpad."); } + */ if ((sources & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD) { Log.v(TAG, "Input device " + device.getName() + " is a gamepad."); } - return (((sources & InputDevice.SOURCE_CLASS_JOYSTICK) == InputDevice.SOURCE_CLASS_JOYSTICK) || - ((sources & InputDevice.SOURCE_DPAD) == InputDevice.SOURCE_DPAD) || - ((sources & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD) - ); + return ((sources & (InputDevice.SOURCE_CLASS_JOYSTICK|InputDevice.SOURCE_GAMEPAD)) != 0); } } From 613920e5b94545fd2074656c1e20903216134f9b Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 19 Oct 2017 18:05:42 -0400 Subject: [PATCH 86/95] audio: Added SDL_AudioStreamFlush(). --- include/SDL_audio.h | 22 ++++++++++- src/audio/SDL_audiocvt.c | 66 +++++++++++++++++++++++++++++-- src/dynapi/SDL_dynapi_overrides.h | 1 + src/dynapi/SDL_dynapi_procs.h | 1 + 4 files changed, 86 insertions(+), 4 deletions(-) diff --git a/include/SDL_audio.h b/include/SDL_audio.h index b30c409269..a242aced4c 100644 --- a/include/SDL_audio.h +++ b/include/SDL_audio.h @@ -545,16 +545,36 @@ extern DECLSPEC int SDLCALL SDL_AudioStreamPut(SDL_AudioStream *stream, const vo extern DECLSPEC int SDLCALL SDL_AudioStreamGet(SDL_AudioStream *stream, void *buf, int len); /** - * Get the number of converted/resampled bytes available + * Get the number of converted/resampled bytes available. The stream may be + * buffering data behind the scenes until it has enough to resample + * correctly, so this number might be lower than what you expect, or even + * be zero. Add more data or flush the stream if you need the data now. * * \sa SDL_NewAudioStream * \sa SDL_AudioStreamPut * \sa SDL_AudioStreamGet * \sa SDL_AudioStreamClear + * \sa SDL_AudioStreamFlush * \sa SDL_FreeAudioStream */ extern DECLSPEC int SDLCALL SDL_AudioStreamAvailable(SDL_AudioStream *stream); +/** + * Tell the stream that you're done sending data, and anything being buffered + * should be converted/resampled and made available immediately. + * + * It is legal to add more data to a stream after flushing, but there will + * be audio gaps in the output. Generally this is intended to signal the + * end of input, so the complete output becomes available. + * + * \sa SDL_NewAudioStream + * \sa SDL_AudioStreamPut + * \sa SDL_AudioStreamGet + * \sa SDL_AudioStreamClear + * \sa SDL_FreeAudioStream + */ +extern DECLSPEC int SDLCALL SDL_AudioStreamFlush(SDL_AudioStream *stream); + /** * Clear any pending data in the stream without converting it * diff --git a/src/audio/SDL_audiocvt.c b/src/audio/SDL_audiocvt.c index 3a10fc9f06..9dba98088d 100644 --- a/src/audio/SDL_audiocvt.c +++ b/src/audio/SDL_audiocvt.c @@ -1362,7 +1362,7 @@ SDL_NewAudioStream(const SDL_AudioFormat src_format, } static int -SDL_AudioStreamPutInternal(SDL_AudioStream *stream, const void *buf, int len) +SDL_AudioStreamPutInternal(SDL_AudioStream *stream, const void *buf, int len, int *maxputbytes) { int buflen = len; int workbuflen; @@ -1479,6 +1479,13 @@ SDL_AudioStreamPutInternal(SDL_AudioStream *stream, const void *buf, int len) printf("AUDIOSTREAM: Final output is %d bytes\n", buflen); #endif + if (maxputbytes) { + const int maxbytes = *maxputbytes; + if (buflen > maxbytes) + buflen = maxbytes; + *maxputbytes -= buflen; + } + /* resamplebuf holds the final output, even if we didn't resample. */ return buflen ? SDL_WriteToDataQueue(stream->queue, resamplebuf, buflen) : 0; } @@ -1524,7 +1531,7 @@ SDL_AudioStreamPut(SDL_AudioStream *stream, const void *buf, int len) we don't need to store it for later, skip the staging process. */ if (!stream->staging_buffer_filled && len >= stream->staging_buffer_size) { - return SDL_AudioStreamPutInternal(stream, buf, len); + return SDL_AudioStreamPutInternal(stream, buf, len, NULL); } /* If there's not enough data to fill the staging buffer, just save it */ @@ -1539,7 +1546,7 @@ SDL_AudioStreamPut(SDL_AudioStream *stream, const void *buf, int len) SDL_assert(amount > 0); SDL_memcpy(stream->staging_buffer + stream->staging_buffer_filled, buf, amount); stream->staging_buffer_filled = 0; - if (SDL_AudioStreamPutInternal(stream, stream->staging_buffer, stream->staging_buffer_size) < 0) { + if (SDL_AudioStreamPutInternal(stream, stream->staging_buffer, stream->staging_buffer_size, NULL) < 0) { return -1; } buf = (void *)((Uint8 *)buf + amount); @@ -1548,6 +1555,58 @@ SDL_AudioStreamPut(SDL_AudioStream *stream, const void *buf, int len) return 0; } +int SDL_AudioStreamFlush(SDL_AudioStream *stream) +{ + if (!stream) { + return SDL_InvalidParamError("stream"); + } + + #if DEBUG_AUDIOSTREAM + printf("AUDIOSTREAM: flushing! staging_buffer_filled=%d bytes\n", stream->staging_buffer_filled); + #endif + + /* shouldn't use a staging buffer if we're not resampling. */ + SDL_assert((stream->dst_rate != stream->src_rate) || (stream->staging_buffer_filled == 0)); + + if (stream->staging_buffer_filled > 0) { + /* push the staging buffer + silence. We need to flush out not just + the staging buffer, but the piece that the stream was saving off + for right-side resampler padding. */ + const SDL_bool first_run = stream->first_run; + const int filled = stream->staging_buffer_filled; + int actual_input_frames = filled / stream->src_sample_frame_size; + if (!first_run) + actual_input_frames += stream->resampler_padding_samples / stream->pre_resample_channels; + + if (actual_input_frames > 0) { /* don't bother if nothing to flush. */ + /* This is how many bytes we're expecting without silence appended. */ + int flush_remaining = ((int) SDL_ceil(actual_input_frames * stream->rate_incr)) * stream->dst_sample_frame_size; + + #if DEBUG_AUDIOSTREAM + printf("AUDIOSTREAM: flushing with padding to get max %d bytes!\n", flush_remaining); + #endif + + SDL_memset(stream->staging_buffer + filled, '\0', stream->staging_buffer_size - filled); + if (SDL_AudioStreamPutInternal(stream, stream->staging_buffer, stream->staging_buffer_size, &flush_remaining) < 0) { + return -1; + } + + /* we have flushed out (or initially filled) the pending right-side + resampler padding, but we need to push more silence to guarantee + the staging buffer is fully flushed out, too. */ + SDL_memset(stream->staging_buffer, '\0', filled); + if (SDL_AudioStreamPutInternal(stream, stream->staging_buffer, stream->staging_buffer_size, &flush_remaining) < 0) { + return -1; + } + } + } + + stream->staging_buffer_filled = 0; + stream->first_run = SDL_TRUE; + + return 0; +} + /* get converted/resampled data from the stream */ int SDL_AudioStreamGet(SDL_AudioStream *stream, void *buf, int len) @@ -1587,6 +1646,7 @@ SDL_AudioStreamClear(SDL_AudioStream *stream) stream->reset_resampler_func(stream); } stream->first_run = SDL_TRUE; + stream->staging_buffer_filled = 0; } } diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h index 07705127f6..ac3980f5fe 100644 --- a/src/dynapi/SDL_dynapi_overrides.h +++ b/src/dynapi/SDL_dynapi_overrides.h @@ -646,3 +646,4 @@ #define SDL_AudioStreamClear SDL_AudioStreamClear_REAL #define SDL_AudioStreamAvailable SDL_AudioStreamAvailable_REAL #define SDL_FreeAudioStream SDL_FreeAudioStream_REAL +#define SDL_AudioStreamFlush SDL_AudioStreamFlush_REAL diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h index e1372ef5b9..8c0f8b7154 100644 --- a/src/dynapi/SDL_dynapi_procs.h +++ b/src/dynapi/SDL_dynapi_procs.h @@ -680,3 +680,4 @@ SDL_DYNAPI_PROC(int,SDL_AudioStreamGet,(SDL_AudioStream *a, void *b, int c),(a,b SDL_DYNAPI_PROC(void,SDL_AudioStreamClear,(SDL_AudioStream *a),(a),) SDL_DYNAPI_PROC(int,SDL_AudioStreamAvailable,(SDL_AudioStream *a),(a),return) SDL_DYNAPI_PROC(void,SDL_FreeAudioStream,(SDL_AudioStream *a),(a),) +SDL_DYNAPI_PROC(int,SDL_AudioStreamFlush,(SDL_AudioStream *a),(a),return) From 5fca706c076f6390a1a6ca49ae52be2e089c8ac6 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 19 Oct 2017 15:37:52 -0700 Subject: [PATCH 87/95] Fixed Android joystick detection --- android-project/src/org/libsdl/app/SDLControllerManager.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/android-project/src/org/libsdl/app/SDLControllerManager.java b/android-project/src/org/libsdl/app/SDLControllerManager.java index 6d97fa8e9a..0419306c27 100644 --- a/android-project/src/org/libsdl/app/SDLControllerManager.java +++ b/android-project/src/org/libsdl/app/SDLControllerManager.java @@ -101,7 +101,9 @@ public static boolean isDeviceSDLJoystick(int deviceId) { Log.v(TAG, "Input device " + device.getName() + " is a gamepad."); } - return ((sources & (InputDevice.SOURCE_CLASS_JOYSTICK|InputDevice.SOURCE_GAMEPAD)) != 0); + return (((sources & InputDevice.SOURCE_CLASS_JOYSTICK) == InputDevice.SOURCE_CLASS_JOYSTICK) || + ((sources & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD) + ); } } From 954cc18874c28b1cb357df6930ca5e6b25d5c03a Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 20 Oct 2017 10:29:22 -0700 Subject: [PATCH 88/95] Reverted changes a970b2ae1bd7 and 4a94743e31fe I don't want to introduce any regressions with Android TV remote support --- android-project/src/org/libsdl/app/SDLControllerManager.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/android-project/src/org/libsdl/app/SDLControllerManager.java b/android-project/src/org/libsdl/app/SDLControllerManager.java index 0419306c27..36294422fc 100644 --- a/android-project/src/org/libsdl/app/SDLControllerManager.java +++ b/android-project/src/org/libsdl/app/SDLControllerManager.java @@ -92,16 +92,15 @@ public static boolean isDeviceSDLJoystick(int deviceId) { if ((sources & InputDevice.SOURCE_CLASS_JOYSTICK) == InputDevice.SOURCE_CLASS_JOYSTICK) { Log.v(TAG, "Input device " + device.getName() + " is a joystick."); } - /* A lot of things are a DPAD that we don't want to use as a joystick (e.g. gpio input, etc.) if ((sources & InputDevice.SOURCE_DPAD) == InputDevice.SOURCE_DPAD) { Log.v(TAG, "Input device " + device.getName() + " is a dpad."); } - */ if ((sources & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD) { Log.v(TAG, "Input device " + device.getName() + " is a gamepad."); } return (((sources & InputDevice.SOURCE_CLASS_JOYSTICK) == InputDevice.SOURCE_CLASS_JOYSTICK) || + ((sources & InputDevice.SOURCE_DPAD) == InputDevice.SOURCE_DPAD) || ((sources & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD) ); } From afdd7955e786570790f3e4bf2fa31ada689e99f4 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 20 Oct 2017 10:45:38 -0700 Subject: [PATCH 89/95] Added SDL_AudioStreamFlush() to the list of new audio stream functions --- WhatsNew.txt | 1 + include/SDL_audio.h | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/WhatsNew.txt b/WhatsNew.txt index 3910359ae7..6f8489e340 100644 --- a/WhatsNew.txt +++ b/WhatsNew.txt @@ -11,6 +11,7 @@ General: SDL_AudioStreamPut SDL_AudioStreamGet SDL_AudioStreamAvailable + SDL_AudioStreamFlush SDL_AudioStreamClear SDL_FreeAudioStream * Added functions to query and set the SDL memory allocation functions: diff --git a/include/SDL_audio.h b/include/SDL_audio.h index a242aced4c..a6acf55bb3 100644 --- a/include/SDL_audio.h +++ b/include/SDL_audio.h @@ -502,6 +502,7 @@ typedef struct _SDL_AudioStream SDL_AudioStream; * \sa SDL_AudioStreamPut * \sa SDL_AudioStreamGet * \sa SDL_AudioStreamAvailable + * \sa SDL_AudioStreamFlush * \sa SDL_AudioStreamClear * \sa SDL_FreeAudioStream */ @@ -523,6 +524,7 @@ extern DECLSPEC SDL_AudioStream * SDLCALL SDL_NewAudioStream(const SDL_AudioForm * \sa SDL_NewAudioStream * \sa SDL_AudioStreamGet * \sa SDL_AudioStreamAvailable + * \sa SDL_AudioStreamFlush * \sa SDL_AudioStreamClear * \sa SDL_FreeAudioStream */ @@ -539,6 +541,7 @@ extern DECLSPEC int SDLCALL SDL_AudioStreamPut(SDL_AudioStream *stream, const vo * \sa SDL_NewAudioStream * \sa SDL_AudioStreamPut * \sa SDL_AudioStreamAvailable + * \sa SDL_AudioStreamFlush * \sa SDL_AudioStreamClear * \sa SDL_FreeAudioStream */ @@ -553,8 +556,8 @@ extern DECLSPEC int SDLCALL SDL_AudioStreamGet(SDL_AudioStream *stream, void *bu * \sa SDL_NewAudioStream * \sa SDL_AudioStreamPut * \sa SDL_AudioStreamGet - * \sa SDL_AudioStreamClear * \sa SDL_AudioStreamFlush + * \sa SDL_AudioStreamClear * \sa SDL_FreeAudioStream */ extern DECLSPEC int SDLCALL SDL_AudioStreamAvailable(SDL_AudioStream *stream); @@ -570,6 +573,7 @@ extern DECLSPEC int SDLCALL SDL_AudioStreamAvailable(SDL_AudioStream *stream); * \sa SDL_NewAudioStream * \sa SDL_AudioStreamPut * \sa SDL_AudioStreamGet + * \sa SDL_AudioStreamAvailable * \sa SDL_AudioStreamClear * \sa SDL_FreeAudioStream */ @@ -582,6 +586,7 @@ extern DECLSPEC int SDLCALL SDL_AudioStreamFlush(SDL_AudioStream *stream); * \sa SDL_AudioStreamPut * \sa SDL_AudioStreamGet * \sa SDL_AudioStreamAvailable + * \sa SDL_AudioStreamFlush * \sa SDL_FreeAudioStream */ extern DECLSPEC void SDLCALL SDL_AudioStreamClear(SDL_AudioStream *stream); @@ -593,6 +598,7 @@ extern DECLSPEC void SDLCALL SDL_AudioStreamClear(SDL_AudioStream *stream); * \sa SDL_AudioStreamPut * \sa SDL_AudioStreamGet * \sa SDL_AudioStreamAvailable + * \sa SDL_AudioStreamFlush * \sa SDL_AudioStreamClear */ extern DECLSPEC void SDLCALL SDL_FreeAudioStream(SDL_AudioStream *stream); From c9a0b6fd476842ad3d1d13e9dd5d598caf58082f Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 20 Oct 2017 14:48:10 -0700 Subject: [PATCH 90/95] Document the SDL audio channel mapping --- include/SDL_audio.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/include/SDL_audio.h b/include/SDL_audio.h index a6acf55bb3..f119c2b267 100644 --- a/include/SDL_audio.h +++ b/include/SDL_audio.h @@ -164,6 +164,15 @@ typedef void (SDLCALL * SDL_AudioCallback) (void *userdata, Uint8 * stream, /** * The calculated values in this structure are calculated by SDL_OpenAudio(). + * + * For multi-channel audio, the default SDL channel mapping is: + * 2: FL FR (stereo) + * 3: FL FR LFE (2.1 surround) + * 4: FL FR BL BR (quad) + * 5: FL FR FC BL BR (quad + center) + * 6: FL FR FC LFE SL SR (5.1 surround - last two can also be BL BR) + * 7: FL FR FC LFE BC SL SR (6.1 surround) + * 8: FL FR FC LFE BL BR SL SR (7.1 surround) */ typedef struct SDL_AudioSpec { From 7cf094388085c349ba6b3e5af18570d5299b4a6f Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 20 Oct 2017 14:51:22 -0700 Subject: [PATCH 91/95] Added a note about adjusting channel weights when converting to fewer channels --- src/audio/SDL_audiocvt.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/audio/SDL_audiocvt.c b/src/audio/SDL_audiocvt.c index 9dba98088d..a3cb4c73de 100644 --- a/src/audio/SDL_audiocvt.c +++ b/src/audio/SDL_audiocvt.c @@ -22,6 +22,9 @@ /* Functions for audio drivers to perform runtime conversion of audio format */ +/* FIXME: Channel weights when converting from more channels to fewer may need to be adjusted, see https://msdn.microsoft.com/en-us/library/windows/desktop/ff819070(v=vs.85).aspx +*/ + #include "SDL.h" #include "SDL_audio.h" #include "SDL_audio_c.h" From d9b330457973ae98879b27963a0c3ac066a36c07 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 20 Oct 2017 16:53:42 -0700 Subject: [PATCH 92/95] Fixed typo converting 4 channel audio to 2 channel --- src/audio/SDL_audiocvt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/audio/SDL_audiocvt.c b/src/audio/SDL_audiocvt.c index a3cb4c73de..d270ab9af1 100644 --- a/src/audio/SDL_audiocvt.c +++ b/src/audio/SDL_audiocvt.c @@ -139,7 +139,7 @@ SDL_ConvertQuadToStereo(SDL_AudioCVT * cvt, SDL_AudioFormat format) dst[1] = (src[1] + src[3]) * 0.5f; /* right */ } - cvt->len_cvt /= 3; + cvt->len_cvt /= 2; if (cvt->filters[++cvt->filter_index]) { cvt->filters[cvt->filter_index] (cvt, format); } From e5ccd5254ad3d4555135c5b7b795385937eca249 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sat, 21 Oct 2017 04:20:57 -0700 Subject: [PATCH 93/95] Fixed bug 3901 - Fix vsync-ed pageflips on the KMSDRM video driver Manuel I noticed that, at least on Intel GPU hardware, passing SDL_RENDERER_PRESENTVSYNC would result on a static console instead of the program graphics. That was due to the fact that calling drmModePageFlip() only works if we have previously set up CRTC to one of the GBM buffers with a drmModeSetCrtc() call, so now it's done and things work as expected. The KMSDRM_GLES_SetupCrtc() call is done only one time, only when needed (when egl_swapinterval is not 0: when it's 0, there's no need for it because we flip by calling drmModePageFlip() anyway). The place where KMSDRM_GLES_SetupCrtc() call is done may look strange, but it's right: it needs EGL completely ready because it needs to call eglSwapBuffers() internally to work (see more comments about it in the code). --- src/video/kmsdrm/SDL_kmsdrmopengles.c | 44 +++++++++++++++++++++++++++ src/video/kmsdrm/SDL_kmsdrmvideo.c | 6 ++++ src/video/kmsdrm/SDL_kmsdrmvideo.h | 1 + 3 files changed, 51 insertions(+) diff --git a/src/video/kmsdrm/SDL_kmsdrmopengles.c b/src/video/kmsdrm/SDL_kmsdrmopengles.c index 7063e5f1a5..7ba663f14f 100644 --- a/src/video/kmsdrm/SDL_kmsdrmopengles.c +++ b/src/video/kmsdrm/SDL_kmsdrmopengles.c @@ -42,6 +42,40 @@ KMSDRM_GLES_LoadLibrary(_THIS, const char *path) { SDL_EGL_CreateContext_impl(KMSDRM) +SDL_bool +KMSDRM_GLES_SetupCrtc(_THIS, SDL_Window * window) { + SDL_WindowData *wdata = ((SDL_WindowData *) window->driverdata); + SDL_DisplayData *displaydata = (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata; + SDL_VideoData *vdata = ((SDL_VideoData *)_this->driverdata); + KMSDRM_FBInfo *fb_info; + + if (!(_this->egl_data->eglSwapBuffers(_this->egl_data->egl_display, wdata->egl_surface))) { + SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "eglSwapBuffers failed on CRTC setup"); + return SDL_FALSE; + } + + wdata->next_bo = KMSDRM_gbm_surface_lock_front_buffer(wdata->gs); + if (wdata->next_bo == NULL) { + SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Could not lock GBM surface front buffer on CRTC setup"); + return SDL_FALSE; + } + + fb_info = KMSDRM_FBFromBO(_this, wdata->next_bo); + if (fb_info == NULL) { + return SDL_FALSE; + } + + if(KMSDRM_drmModeSetCrtc(vdata->drm_fd, displaydata->crtc_id, fb_info->fb_id, + 0, 0, &vdata->saved_conn_id, 1, &displaydata->cur_mode) != 0) { + SDL_LogWarn(SDL_LOG_CATEGORY_VIDEO, "Could not set up CRTC to a GBM buffer"); + return SDL_FALSE; + + } + + wdata->crtc_ready = SDL_TRUE; + return SDL_TRUE; +} + int KMSDRM_GLES_SetSwapInterval(_THIS, int interval) { if (!_this->egl_data) { return SDL_SetError("EGL not initialized"); @@ -118,6 +152,16 @@ KMSDRM_GLES_SwapWindow(_THIS, SDL_Window * window) { } } else { /* Queue page flip at vsync */ + + /* Have we already setup the CRTC to one of the GBM buffers? Do so if we have not, + or FlipPage won't work in some cases. */ + if (!wdata->crtc_ready) { + if(!KMSDRM_GLES_SetupCrtc(_this, window)) { + SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Could not set up CRTC for doing vsync-ed pageflips"); + return 0; + } + } + /* SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "drmModePageFlip(%d, %u, %u, DRM_MODE_PAGE_FLIP_EVENT, &wdata->waiting_for_flip)", vdata->drm_fd, displaydata->crtc_id, fb_info->fb_id); */ ret = KMSDRM_drmModePageFlip(vdata->drm_fd, displaydata->crtc_id, fb_info->fb_id, diff --git a/src/video/kmsdrm/SDL_kmsdrmvideo.c b/src/video/kmsdrm/SDL_kmsdrmvideo.c index 63376f213a..ee3ac0592a 100644 --- a/src/video/kmsdrm/SDL_kmsdrmvideo.c +++ b/src/video/kmsdrm/SDL_kmsdrmvideo.c @@ -522,6 +522,12 @@ KMSDRM_CreateWindow(_THIS, SDL_Window * window) } #endif /* SDL_VIDEO_OPENGL_EGL */ + /* Window is created, but we have yet to set up CRTC to one of the GBM buffers if we want + drmModePageFlip to work, and we can't do it until EGL is completely setup, because we + need to do eglSwapBuffers so we can get a valid GBM buffer object to call + drmModeSetCrtc on it. */ + wdata->crtc_ready = SDL_FALSE; + /* Setup driver data for this window */ window->driverdata = wdata; diff --git a/src/video/kmsdrm/SDL_kmsdrmvideo.h b/src/video/kmsdrm/SDL_kmsdrmvideo.h index 307c475dce..71f0de722b 100644 --- a/src/video/kmsdrm/SDL_kmsdrmvideo.h +++ b/src/video/kmsdrm/SDL_kmsdrmvideo.h @@ -62,6 +62,7 @@ typedef struct SDL_WindowData struct gbm_bo *current_bo; struct gbm_bo *next_bo; SDL_bool waiting_for_flip; + SDL_bool crtc_ready; #if SDL_VIDEO_OPENGL_EGL EGLSurface egl_surface; #endif From 212a272bb26c5d41105efa33945a2da35f0b0a16 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sat, 21 Oct 2017 22:26:24 -0700 Subject: [PATCH 94/95] Added Visual Studio solution files for WinRT projects --- VisualC-WinRT/UWP_VS2015/SDL-UWP.sln | 34 +++++++++++++++++++ .../WinPhone80_VS2012/SDL-WinPhone80.sln | 26 ++++++++++++++ .../WinPhone81_VS2013/SDL-WinPhone81.sln | 28 +++++++++++++++ VisualC-WinRT/WinRT81_VS2013/SDL-WinRT81.sln | 34 +++++++++++++++++++ 4 files changed, 122 insertions(+) create mode 100644 VisualC-WinRT/UWP_VS2015/SDL-UWP.sln create mode 100644 VisualC-WinRT/WinPhone80_VS2012/SDL-WinPhone80.sln create mode 100644 VisualC-WinRT/WinPhone81_VS2013/SDL-WinPhone81.sln create mode 100644 VisualC-WinRT/WinRT81_VS2013/SDL-WinRT81.sln diff --git a/VisualC-WinRT/UWP_VS2015/SDL-UWP.sln b/VisualC-WinRT/UWP_VS2015/SDL-UWP.sln new file mode 100644 index 0000000000..0a786e7d83 --- /dev/null +++ b/VisualC-WinRT/UWP_VS2015/SDL-UWP.sln @@ -0,0 +1,34 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.25420.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SDL2-UWP", "SDL-UWP.vcxproj", "{89E9B32E-A86A-47C3-A948-D2B1622925CE}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|ARM = Debug|ARM + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|ARM = Release|ARM + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {89E9B32E-A86A-47C3-A948-D2B1622925CE}.Debug|ARM.ActiveCfg = Debug|ARM + {89E9B32E-A86A-47C3-A948-D2B1622925CE}.Debug|ARM.Build.0 = Debug|ARM + {89E9B32E-A86A-47C3-A948-D2B1622925CE}.Debug|x64.ActiveCfg = Debug|x64 + {89E9B32E-A86A-47C3-A948-D2B1622925CE}.Debug|x64.Build.0 = Debug|x64 + {89E9B32E-A86A-47C3-A948-D2B1622925CE}.Debug|x86.ActiveCfg = Debug|Win32 + {89E9B32E-A86A-47C3-A948-D2B1622925CE}.Debug|x86.Build.0 = Debug|Win32 + {89E9B32E-A86A-47C3-A948-D2B1622925CE}.Release|ARM.ActiveCfg = Release|ARM + {89E9B32E-A86A-47C3-A948-D2B1622925CE}.Release|ARM.Build.0 = Release|ARM + {89E9B32E-A86A-47C3-A948-D2B1622925CE}.Release|x64.ActiveCfg = Release|x64 + {89E9B32E-A86A-47C3-A948-D2B1622925CE}.Release|x64.Build.0 = Release|x64 + {89E9B32E-A86A-47C3-A948-D2B1622925CE}.Release|x86.ActiveCfg = Release|Win32 + {89E9B32E-A86A-47C3-A948-D2B1622925CE}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/VisualC-WinRT/WinPhone80_VS2012/SDL-WinPhone80.sln b/VisualC-WinRT/WinPhone80_VS2012/SDL-WinPhone80.sln new file mode 100644 index 0000000000..f5090305c9 --- /dev/null +++ b/VisualC-WinRT/WinPhone80_VS2012/SDL-WinPhone80.sln @@ -0,0 +1,26 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2012 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SDL2-WinPhone80", "SDL-WinPhone80.vcxproj", "{33048AF1-031A-4CE6-B61E-FAD2DB832E9E}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|ARM = Debug|ARM + Debug|Win32 = Debug|Win32 + Release|ARM = Release|ARM + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {33048AF1-031A-4CE6-B61E-FAD2DB832E9E}.Debug|ARM.ActiveCfg = Debug|ARM + {33048AF1-031A-4CE6-B61E-FAD2DB832E9E}.Debug|ARM.Build.0 = Debug|ARM + {33048AF1-031A-4CE6-B61E-FAD2DB832E9E}.Debug|Win32.ActiveCfg = Debug|Win32 + {33048AF1-031A-4CE6-B61E-FAD2DB832E9E}.Debug|Win32.Build.0 = Debug|Win32 + {33048AF1-031A-4CE6-B61E-FAD2DB832E9E}.Release|ARM.ActiveCfg = Release|ARM + {33048AF1-031A-4CE6-B61E-FAD2DB832E9E}.Release|ARM.Build.0 = Release|ARM + {33048AF1-031A-4CE6-B61E-FAD2DB832E9E}.Release|Win32.ActiveCfg = Release|Win32 + {33048AF1-031A-4CE6-B61E-FAD2DB832E9E}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/VisualC-WinRT/WinPhone81_VS2013/SDL-WinPhone81.sln b/VisualC-WinRT/WinPhone81_VS2013/SDL-WinPhone81.sln new file mode 100644 index 0000000000..1d8347489d --- /dev/null +++ b/VisualC-WinRT/WinPhone81_VS2013/SDL-WinPhone81.sln @@ -0,0 +1,28 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.40629.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SDL2-WinPhone81", "SDL-WinPhone81.vcxproj", "{48FADC0E-964D-4DAB-BCED-372E0AD19577}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|ARM = Debug|ARM + Debug|Win32 = Debug|Win32 + Release|ARM = Release|ARM + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {48FADC0E-964D-4DAB-BCED-372E0AD19577}.Debug|ARM.ActiveCfg = Debug|ARM + {48FADC0E-964D-4DAB-BCED-372E0AD19577}.Debug|ARM.Build.0 = Debug|ARM + {48FADC0E-964D-4DAB-BCED-372E0AD19577}.Debug|Win32.ActiveCfg = Debug|Win32 + {48FADC0E-964D-4DAB-BCED-372E0AD19577}.Debug|Win32.Build.0 = Debug|Win32 + {48FADC0E-964D-4DAB-BCED-372E0AD19577}.Release|ARM.ActiveCfg = Release|ARM + {48FADC0E-964D-4DAB-BCED-372E0AD19577}.Release|ARM.Build.0 = Release|ARM + {48FADC0E-964D-4DAB-BCED-372E0AD19577}.Release|Win32.ActiveCfg = Release|Win32 + {48FADC0E-964D-4DAB-BCED-372E0AD19577}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/VisualC-WinRT/WinRT81_VS2013/SDL-WinRT81.sln b/VisualC-WinRT/WinRT81_VS2013/SDL-WinRT81.sln new file mode 100644 index 0000000000..be543c931a --- /dev/null +++ b/VisualC-WinRT/WinRT81_VS2013/SDL-WinRT81.sln @@ -0,0 +1,34 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.40629.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SDL2-WinRT81", "SDL-WinRT81.vcxproj", "{C8DF6173-06A1-4F56-A9BC-2002596B30E9}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|ARM = Debug|ARM + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|ARM = Release|ARM + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {C8DF6173-06A1-4F56-A9BC-2002596B30E9}.Debug|ARM.ActiveCfg = Debug|ARM + {C8DF6173-06A1-4F56-A9BC-2002596B30E9}.Debug|ARM.Build.0 = Debug|ARM + {C8DF6173-06A1-4F56-A9BC-2002596B30E9}.Debug|Win32.ActiveCfg = Debug|Win32 + {C8DF6173-06A1-4F56-A9BC-2002596B30E9}.Debug|Win32.Build.0 = Debug|Win32 + {C8DF6173-06A1-4F56-A9BC-2002596B30E9}.Debug|x64.ActiveCfg = Debug|x64 + {C8DF6173-06A1-4F56-A9BC-2002596B30E9}.Debug|x64.Build.0 = Debug|x64 + {C8DF6173-06A1-4F56-A9BC-2002596B30E9}.Release|ARM.ActiveCfg = Release|ARM + {C8DF6173-06A1-4F56-A9BC-2002596B30E9}.Release|ARM.Build.0 = Release|ARM + {C8DF6173-06A1-4F56-A9BC-2002596B30E9}.Release|Win32.ActiveCfg = Release|Win32 + {C8DF6173-06A1-4F56-A9BC-2002596B30E9}.Release|Win32.Build.0 = Release|Win32 + {C8DF6173-06A1-4F56-A9BC-2002596B30E9}.Release|x64.ActiveCfg = Release|x64 + {C8DF6173-06A1-4F56-A9BC-2002596B30E9}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal From cf1d5d309d93bca88ea7d5511b63f1e2560fb11c Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Sun, 22 Oct 2017 20:24:58 +0200 Subject: [PATCH 95/95] Don't X error in SDL_CreateWindow with unsupported GL attributes --- src/video/x11/SDL_x11opengl.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/video/x11/SDL_x11opengl.c b/src/video/x11/SDL_x11opengl.c index ab1bf58ca1..922c096173 100644 --- a/src/video/x11/SDL_x11opengl.c +++ b/src/video/x11/SDL_x11opengl.c @@ -463,7 +463,9 @@ X11_GL_InitExtensions(_THIS) } } - X11_XDestroyWindow(display, w); + if (w) { + X11_XDestroyWindow(display, w); + } X11_PumpEvents(_this); }